在编辑Word中,我们经常遇到有时需要对一个字进行编辑,有时需要对一段文字进行编辑,一个字或者一行字的编辑行为是相同的。抽象出来就是整体部分的关系,对应就是组合设计模式。
组合设计模式,有时又叫作整体-部分(Whole-Part)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的操作性与访问性,属于结构型设计模式。
组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,顶层的节点被称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点。
组合模式结构与实现并不复杂,主要就是抽象构建(Component)角色,其次是树叶(Leaf)角色与树枝(Composite)构件角色。
抽象构件角色分为透明模式与安全模式。
透明模式,抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。但其缺点是:树叶构件本来没有 Add()、Remove() 及 GetChild() 方法,却要实现它们(空实现或抛异常),这样会带来一些安全性问题。图片来自引用2。
安全模式,将管理子构件的方法移到树枝构件中,抽象构件和树叶构件没有对子对象的管理方法,这样就避免了上一种方式的安全性问题,但由于叶子和分支有不同的接口,客户端在调用时要知道树叶对象和树枝对象的存在,所以失去了透明性。图片来自引用2。
主要优点有:
其主要缺点是:
1.在需要表示一个对象整体与部分的层次结构的场合。
2.要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。
以我现在所在单位为例,抽象了一个模型,如下图所示:
public interface Company {
/**
* 获取公司名称
* @return 名称
*/
String getName();
/**
* 添加
* @param c 公司
*/
void add(Company c);
/**
* 移除
* @param c 公司
*/
void remove(Company c);
/**
* 显示
* @param depth 层级
*/
void disPlay(int depth);
/**
* 展示职责
*/
void displayDuty();
}
public class ConcreteCompany implements Company{
private final List children = new ArrayList<>();
private final String name;
public ConcreteCompany(String name){
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void add(Company c) {
children.add(c);
}
@Override
public void remove(Company c) {
children.remove(c);
}
@Override
public void disPlay(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + getName());
for (Company c: children) {
c.disPlay(depth + 2);
}
}
@Override
public void displayDuty() {
for (Company c: children) {
c.displayDuty();
}
}
}
public class HumanResourceDepartment implements Company{
private String name;
public HumanResourceDepartment(String name){
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void add(Company c) {
}
@Override
public void remove(Company c) {
}
@Override
public void disPlay(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + getName());
}
@Override
public void displayDuty() {
System.out.println(MessageFormat.format("{0}负责管理公司人事所有事务", name));
}
}
public class FinanceDepartment implements Company {
private String name;
public FinanceDepartment(String name){
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void add(Company c) {
}
@Override
public void remove(Company c) {
}
@Override
public void disPlay(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(sb.toString() + getName());
}
@Override
public void displayDuty() {
System.out.println(MessageFormat.format("{0}负责管理公司财务所有事务", name));
}
}
public class Main {
public static void main(String[] args) {
//海南分院
ConcreteCompany haiNanBranch = new ConcreteCompany("海南分院");
haiNanBranch.add(new HumanResourceDepartment("海南分院人事处"));
haiNanBranch.add(new FinanceDepartment("海南分院财务处"));
//云南分院
ConcreteCompany yunNanBranch = new ConcreteCompany("云南分院");
yunNanBranch.add(new HumanResourceDepartment("云南分院人事处"));
yunNanBranch.add(new FinanceDepartment("云南分院财务处"));
//总院
ConcreteCompany institute = new ConcreteCompany("天津总院");
institute.add(new HumanResourceDepartment("总院人力资源部"));
institute.add(new FinanceDepartment("总院资产财务部"));
institute.add(haiNanBranch);
institute.add(yunNanBranch);
System.out.println("结构图:");
institute.disPlay(0);
System.out.println("\n职责:");
institute.displayDuty();
}
}
1.《大话设计模式》
2.组合模式(详解版)
design-pattern-learning/src/com/hz/design/pattern/composite at main · airhonor/design-pattern-learning · GitHub