组合模式
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
一致性指的是这些对象都具有相同的接口。
优点:
- 高层模块调用简单
- 节点自有增加,容易扩展。
缺点:
直接调用实现类,不符合依赖倒置原则。
使用场景
- 维护和展示部分整体关系场景,如菜单、文件和文件夹管理等。
- 从一个整体中能够独立出部分模块或功能的场景。
透明方式
父类包含所有子类方法,父类方法是抽象的。不需要该方法的子类可以选择throw Exception。
优点:
各个子类完全一致,可以使用父类接口调用。
缺点:
子类实现无意义方法。
安全方式
子类特有的方法,留到具体子类中实现。树枝节点和树叶节点彻底分开。
缺点:
所有子类不再具有相同接口。
代码实现
GitHub
例子是透明方式实现的组合模式
Compent 抽象构件,定义参加组合对象的共有方法和属性。
代码语言:javascript复制public abstract class Component { protected String name; public Component(String name){ this.name = name; } abstract void add(Component component); abstract void delete(Component component); abstract void show(int index);}
Composite树枝构件,组合树枝节点和树叶节点形成一个树形结构。
代码语言:javascript复制public class Composite extends Component { List<Component> components = new ArrayList<>(); public Composite(String name){ super(name); } @Override void add(Component component) { components.add(component); } @Override void delete(Component component) { components.remove(component); } @Override void show(int index) { StringBuilder stringBuilder = new StringBuilder(); for(int i = 0; i < index; i ){ stringBuilder.append("-"); } System.out.println(stringBuilder.toString() this.name); for(Component component : components){ component.show(index 2); } }}
Leaf树叶节点,其下没有其他分支
代码语言:javascript复制public class Leaf extends Component { public Leaf(String name){ super(name); } @Override void add(Component component) { System.out.println("树叶节点没有此功能"); } @Override void delete(Component component) { System.out.println("树叶节点没有此功能"); } @Override void show(int index) { StringBuilder stringBuilder = new StringBuilder(); for(int i = 0; i < index; i ){ stringBuilder.append("-"); } System.out.println(stringBuilder.toString() this.name); }}
测试类
代码语言:javascript复制public static void main(String[] args){ Composite root = new Composite("root"); root.add(new Leaf("leaf1")); Leaf leaf = new Leaf("leaf2"); root.add(leaf); Composite composite = new Composite("composite"); composite.add(new Leaf("leaf3")); composite.add(new Leaf("leaf4")); composite.add(new Leaf("leaf5")); root.add(composite); root.show(1); System.out.println("==================="); root.delete(leaf); root.show(1); System.out.println("==================="); composite.show(1);}
返回信息
代码语言:javascript复制-root---leaf1---leaf2---composite-----leaf3-----leaf4-----leaf5===================-root---leaf1---composite-----leaf3-----leaf4-----leaf5===================-composite---leaf3---leaf4---leaf5