设计模式----组合模式

组合模式属于对象的结构型模型,他将对象组织到树形结构中,用来描述整体和部分的关系。

Gof给的定义:组合模式组合成多个对象形成树形结构表示整体-部分的结构层次。组合模式将单个对象和组合对象(容器对象)的使用具有一致性

解决的问题:

针对客户端代码过多依赖于容器对象内部的复杂结构,如果容器对象内部结构发生改变,则客户端代码也需要过多的修改,从而导致代码维护性差、扩展性差等弊端。

应用场景:

当需求中体现的是部分与整体层次的结构时,以及希望用户代码忽略组合对象与单个对象的不同,统一使用组合结构中的所有对象时就应该考虑使用组合模式。

组合模式的UML类图如下

客户端(Client)

抽象构件(Component) 

接口或者抽象类,为叶子构件和容器构件对象声明接口,报案了所有子类的共有行为的声明和实现,在抽象构件中定义了访问及管理它的子构建的方法:增加、删除、获取子构建、构件描述等

叶子构件(leaf)

在组合结构中表示叶子节点对象,在叶子节点中实现抽象构件中定义的行为,对于访问和管理子构建的方法通过异常的方式抛出

容器构件(Composite)

容器节点对象,可以有子节点,子节点可以是叶子节点构件也可以是容器构件,在其内部提供一个集合用于存储子节点,实现抽象构建中的定义的所有行为和管理访问子构件的方法,并通过递归的方式调用其子节点。

举例:

public abstract class Component {

    abstract void printStruct(String preStr);
    public void addChild(Component child){
        throw new UnsupportedOperationException("对象不支持这个功能");
    }
    public Component getChildren(int index){
        throw new UnsupportedOperationException("对象不支持这个功能");
    }
    public void removeChild(Component child){
        throw new UnsupportedOperationException("对象不支持这个功能");
    }
}

public class Leaf extends Component{

    private String name;

    public Leaf(String name) {
        this.name = name;
    }

    @Override
    void printStruct(String preStr) {
        System.out.println(preStr + "--" + name);
    }

}

public class Composite extends Component {

    private List<Component> childComponent = null;//存储对象中包含的子组件对象
    private String name;//组合对象的名字

    public Composite(String name) {
        this.name = name;
    }

    @Override
    void printStruct(String preStr) {
        //先将自己(也就是父目录输出)
        System.out.println(preStr + "--" + name);
        //如果包含组件则输出这些子组件对象
        if (this.childComponent != null){
            //向后缩进一格
            preStr += " ";

            //输出当前对象的子对象
            for (Component component : childComponent){
                component.printStruct(preStr);
            }
        }
    }

    @Override
    public void addChild(Component child){
        //延迟初始化
        if (childComponent == null){
            childComponent = new ArrayList<>();
        }
        childComponent.add(child);
    }
}
public class Test {
    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("裤子");
        root.addChild(c1);
        root.addChild(c2);
        c1.addChild(leaf1);
        c1.addChild(leaf2);
        c2.addChild(leaf3);
        root.printStruct(" ");
    }
}

 测试结果:

 --服装
  --男装
   --夹克
   --衬衣
  --女装
   --裤子

参考:《Java设计模式》于卫红编著

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值