模式定义
将对象组合成树型结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
模式结构
代码实现
public abstract class Component {
//输出组件自身名称
public abstract void printStruct(String preStr);
public void addChild(Component child){}
public void removeChild(Component child){}
//返回某个索引对应的组件对象
public Component getChild(int index){
return null;
};
}
public class Composite extends Component {
private String name;
private List<Component> components;
public Composite(String name) {
this.name = name;
}
public void addChild(Component child) {
if (components == null) {
components = new ArrayList<Component>();
}
components.add(child);
}
@Override
public void printStruct(String preStr) {
//先输出自己
System.out.println(preStr + "+" + name);
//输出自组件
if (components != null) {
preStr += " ";
for (Component component : components) {
component.printStruct(preStr);
}
}
}
}
@AllArgsConstructor
public class Leaf extends Component {
private String name;
@Override
public void printStruct(String preStr) {
System.out.println(preStr + "-" + name);
}
}
public class Client {
public static void main(String[] args) {
//定义所有组合对象
Component root = new Composite("服装");
Component c1 = new Composite("男装");
Component c2 = new Composite("女装");
//叶子节点
Component leaf1 = new Leaf("衬衣");
Component leaf2 = new Leaf("夹克");
Component leaf3 = new Leaf("裙子");
Component leaf4 = new Leaf("套装");
root.addChild(c1);
root.addChild(c2);
c1.addChild(leaf1);
c1.addChild(leaf2);
c2.addChild(leaf3);
c2.addChild(leaf4);
root.printStruct("");
}
}
模式的优缺点
优点
定义了包含基本对象和组合对象的类层次结构
统一了组合对象和叶子对象
在组合模式中,可以把叶子对象当作特殊的组合对象看待,为它们定义统一的父类,从而把组合对象和叶子对象的行为统一起来。更容易扩展
由于客户端是统一地面对Component来操作,因此,新定义的Composite或Leaf子类能够很容易地与已有的结构一起工作,而客户端不需要为增添了新的组建类而改变。
缺点
- 在组合模式时中,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
思考
模式本质:统一叶子对象和组合对象。
开发中的应用场景
当你想表示对象的部分-整体层次结构,可以选用组合模式,把整体和部分的操作统一起来,使得层次结构实现更简单,从外部来使用这个层次结构也容易。
如果你希望统一的使用组合结构中的所有对象。