设计模式之接口型模式-组合模式(合成模式)

组合模式是什么?

组合模式(又为‘部分-整体’模式)屏蔽了容器对象与单个对象在使用时的差异,为客户端提供统一的接口操作,从而降低客户端代码与被调用对象之间的耦合关系,方便系统的维护和扩展。

组合模式的要素

1.抽象构件角色(Component):定义参加组合的对象的共有方法和属性,可以定义一些默认的行为或属性。

2.叶子构件(Leaf):叶子对象,其下再也没有其他的分支。

3.树枝构件(Composite):树枝对象,它的作用是组合树枝节点和叶子节点;

组合模式的两种模式:透明模式和安全模式

组合模式-安全模式示意图
组合模式-透明模式示意图

从类图上大家应该能看清楚了,这两种模式各有优缺点,透明模式是把用来组合使用的方法放到抽象类中,比如add(),remove()以及Display等方法,不管叶子对象还是树枝对象都有相同的结构,通过判断是Display的返回值确认是叶子节点还是树枝节点,如果处理不当,这个会在运行期出现问题的,不是很建议的方式;安全模式就不同了,它是把树枝节点和树叶节点彻底分开,树枝节点单独拥有用来组合的方法,这种方法比较安全。

组合模式的优点有哪些呢?

第一个优点只要是树形结构,就要考虑使用组合模式,这个一定记住,只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式吧。

package myDesignPatternsTest.InferMode.CombinationModel;

/**
 * 公共抽象类
 */
public abstract class Crop {
    private String name="";
    private String position="";
    private  int salary=0;

    public Crop(String name, String position, int salary) {
        this.name = name;
        this.position = position;
        this.salary = salary;
    }
    public String  getInfo(){
        String  info="";
        info="姓名:"+this.name;
        info+="职位:"+this.position;
        info+="薪水:"+this.salary;
        return info;
    }
}
package myDesignPatternsTest.InferMode.CombinationModel;

/**
 * 这个就是最最最小的单位了
 */
public class Leaf extends Crop {
    public Leaf(String name, String position, int salary) {
        super(name, position, salary);
    }
}
package myDesignPatternsTest.InferMode.CombinationModel;

import java.util.ArrayList;

/**
 * 这个就是树节点
 */
public class Branch extends  Crop {
    ArrayList<Crop> list=new ArrayList<Crop>();
    public Branch(String name, String position, int salary) {
        super(name, position, salary);
    }
    public  void  addSubordinate(Crop crop){
           this.list.add(crop);
    }

    public ArrayList<Crop> getList() {
        return this.list;
    }
}
package myDesignPatternsTest.InferMode.CombinationModel;

import java.util.ArrayList;

public class Client {
    public static void main(String[] args) {
        //首先是组装一个组织结构出来
        Branch ceo = compositionCropTree();
        //首先把CEO的信息打印出来:
        System.out.println(ceo.getInfo());
        //然后是所有员工信息
        System.out.println(getTreeInfo(ceo));

    }
    public static Branch compositionCropTree(){
        Branch root = new Branch("张老大","总经理",50000);
        //三个部门经理
        Branch developDep  = new Branch("刘老二","研发部门经理",30000);
        Branch financeDep   = new Branch("王老二","财务部门经理",20000);
        Branch salesDep  = new Branch("刘大嘴","销售部门经理",20000);
        //再把二个小组长产生出来
        Branch firstDevGroup = new Branch("杨三乜斜","开发一组组长",5000);
        Branch secondDevGroup = new Branch("吴大棒槌","开发二组组长",6000);
        //再把公司所有的员工列出来
        Leaf a = new Leaf("a","开发人员",2000);
        Leaf b = new Leaf("b","开发人员",2000);
        Leaf c = new Leaf("c","开发人员",2000);
        Leaf d = new Leaf("d","开发人员",2000);
        Leaf e = new Leaf("e","开发人员",2000);
        Leaf f = new Leaf("f","开发人员",2000);
        Leaf g = new Leaf("g","开发人员",2000);
        Leaf h = new Leaf("h","销售人员",5000);
        Leaf i = new Leaf("i","销售人员",4000);
        Leaf j = new Leaf("j","财务人员",5000);
        Leaf k = new Leaf("k","CEO秘书",8000);
        Leaf zhengLaoLiu = new Leaf("郑老六","研发部副经理",20000);
        // 开始组装
        //1.老大下面有三个部门
        root.addSubordinate(k);
        root.addSubordinate(developDep);
        root.addSubordinate(financeDep);
        root.addSubordinate(salesDep);

        //2.研发部下面有2个组长一个副经理
        developDep.addSubordinate(firstDevGroup);
        developDep.addSubordinate(secondDevGroup);
        developDep.addSubordinate(zhengLaoLiu);
        //3.两个研发组下面各有几个员工
        firstDevGroup.addSubordinate(a);
        firstDevGroup.addSubordinate(b);
        firstDevGroup.addSubordinate(c);
        secondDevGroup.addSubordinate(d);
        secondDevGroup.addSubordinate(e);
        secondDevGroup.addSubordinate(f);
        secondDevGroup.addSubordinate(g);
        //4.将销售人员和财务人员放到各自的部门
        financeDep.addSubordinate(j);
        salesDep.addSubordinate(h);
        salesDep.addSubordinate(i);

        return root;
    }
    public static String getTreeInfo(Branch root){
        ArrayList<Crop> subordinateList = root.getList();
        String info = "";
        for(Crop s :subordinateList){
            if(s instanceof Leaf){ //是员工就直接获得信息
                info = info + s.getInfo()+"\n";
            }else{ //是个小头目
                info = info + s.getInfo() +"\n"+ getTreeInfo((Branch)s);
            }
        }
        return info;
    }

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1-木2-林3-森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值