一、什么是组合模式
组合(Composite Pattern)模式的定义:有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性。
组合模式包含以下主要角色包含以下主要角色:
- 树叶抽象构件(Component)角色:它的主要作用是为树叶构件声明公共接口,并实现它们的默认行为。
- 树枝抽象构件(BranchComponent)角色:它的主要作用是为树枝构件声明公共接口,并实现它们的默认行为,扩展了树叶抽象角色。
- 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。
- 树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。
二、享元模式的实现
组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,顶层的节点被称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点。
- 树叶抽象构件(Component)
/**
* @author FluffyCatkin
* @version 1.0
* @date 2020/1/6 0006 15:56
* @description 抽象构件(Component)角色:它的主要作用是为树叶构件声明公共接口,并实现它们的默认行为。
*/
@FunctionalInterface
public interface Component {void operation();
}
- 树叶构件(Leaf)
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 16:01* @description 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。*/
public class Leaf implements Component {private String leafName;public Leaf(String leafName) {this.leafName = leafName;}@Overridepublic void operation() {System.out.println("叶子节点:"+leafName+"被调用!");}}
- 树枝抽象构件(BranchComponent)
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 15:56* @description 树枝抽象构件(BranchComponent)角色:它的主要作用是为树枝构件声明公共接口,并实现它们的默认行为,扩展了树叶抽象角色。*/
public interface BranchComponent extends Component{/*** 新增叶子* @param component 叶子*/void add(Component component);/*** 移除叶子* @param component 叶子*/void remove(Component component);/*** 查找叶子* @param index 叶子下标* @return 叶子*/Component getChild(int index);
}
- 树枝构件(Composite)
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 16:01* @description 树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法*/
public class Composite implements BranchComponent {private List<Component> children = new ArrayList<>();private String compositeName ;public Composite(String compositeName) {this.compositeName = compositeName;}@Overridepublic void operation() {System.out.println("树枝:"+compositeName+"被调用!");children.parallelStream().forEach(Component::operation);}/*** 新增叶子* @param component 叶子*/@Overridepublic void add(Component component){children.add(component);}/*** 移除叶子* @param component 叶子*/@Overridepublic void remove(Component component){children.remove(component);}/*** 查找叶子* @param index 叶子下标* @return 叶子*/@Overridepublic Component getChild(int index){return children.get(index);}
}
- 测试类
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/6 0006 15:53* @description 组合模式** 在现实生活中,存在很多“部分-整体”的关系,例如,大学中的部门与学院、总公司中的部门与分公司、学习用品中的书与书包、生活用品中的衣月艮与衣柜以及厨房中的锅碗瓢盆等。在软件开发中也是这样,例如,文件系统中的文件与文件夹、窗体程序中的简单控件与容器控件等。对这些简单对象与复合对象的处理,如果用组合模式来实现会很方便。* 组合模式的定义与特点:* 组合(Composite)模式的定义:有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。* 组合模式的主要优点有:组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;* 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;** 其主要缺点是:设计较复杂,客户端需要花更多时间理清类之间的层次关系;* 不容易限制容器中的构件;* 不容易用继承的方法来增加构件的新功能;* 模式的结构:* 组合模式包含以下主要角色。* 树叶抽象构件(Component)角色:它的主要作用是为树叶构件声明公共接口,并实现它们的默认行为。* 树枝抽象构件(Component)角色:它的主要作用是为树枝构件声明公共接口,并实现它们的默认行为,扩展了树叶抽象角色。* 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。* 树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。** 组合模式的应用场景:* 前面分析了组合模式的结构与特点,下面分析它适用的以下应用场景。在需要表示一个对象整体与部分的层次结构的场合。* 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。**/
public class Main {/*** 测试组合模式*/@Testpublic void compositeTest(){//组装树形结构Composite composite1 = new Composite("树枝1");Composite composite2 = new Composite("树枝2");Leaf leaf1 = new Leaf("叶子1");Leaf leaf2 = new Leaf("叶子2");Leaf leaf3 = new Leaf("叶子3");composite1.add(leaf1);composite1.add(composite2);composite2.add(leaf2);composite2.add(leaf3);//遍历composite1.operation();}
}
执行结果:
树枝:树枝1被调用!
树枝:树枝2被调用!
叶子节点:叶子3被调用!
叶子节点:叶子2被调用!
叶子节点:叶子1被调用!Process finished with exit code 0
三、应用场景
它适用的以下应用场景:
- 在需要表示一个对象整体与部分的层次结构的场合。
- 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。
四、优缺点分析
组合模式的主要优点有:
- 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;
- 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;
其主要缺点是:
- 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
- 不容易限制容器中的构件;
- 不容易用继承的方法来增加构件的新功能;
代码地址:https://gitee.com/fluffycatkin/JavaDesignModel.git
原文出处:http://c.biancheng.net/view/1373.html