大话设计模式-组合模式学习总结

来源:互联网 发布:辐射4灵光优化 编辑:程序博客网 时间:2024/05/21 13:57

一、概念

组合模式:将对象组合成树型结构以表示部分-整体的层次结构,组合模式使用户对单个对象和组合对象的使用具有一致性。

二、类图及基本代码

这里写图片描述

Leaf是叶子节点,没有子节点。
Composite是枝节点,用于存储子部件,实现与子部件相关的行为,如Add,Remove等。
Component是一个接口,用于访问和管理子部件。

/* * 声明一个接口负责访问和管理Component的子部件 */public abstract class Component {    protected String name;    public Component(String name){        this.name=name;    }    public abstract void Add(Component component);    public abstract void Remove(Component component);    public abstract void Display(int depth);}
/* * 定义有枝节点行为,用来存储子部件 */public class Composite extends Component{    private List<Component> list=new ArrayList();    public Composite(String name) {        super(name);    }    @Override    public void Add(Component component) {        list.add(component);    }    @Override    public void Remove(Component component) {        list.remove(component);    }    @Override    public void Display(int depth) {        String string="";        for(int i=0;i<depth;i++){            string+="-";        }        System.out.println(string+name);        //展示枝节点上的所有节点        for (Component component : list) {            component.Display(depth+2);        }    }}
/* * 叶子节点 */public class Leaf extends Component{    public Leaf(String name) {        super(name);    }    @Override    public void Add(Component component) {        System.out.println("Cann't add to a leaf");    }    @Override    public void Remove(Component component) {        System.out.println("Cann't remove from a leaf");    }    //展示    @Override    public void Display(int depth) {        String string="";        for(int i=0;i<depth;i++){            string+="-";        }        System.out.println(string+name);    }}
package com.hwj.www.model19.version1;public class Show {    public static void main(String[] args) {        Composite root=new Composite("root");//root节点        root.Add(new Leaf("Leaf A"));//主节点上放入两个叶子节点        root.Add(new Leaf("Leaf B"));        Composite composite=new Composite("Composite X");        composite.Add(new Leaf("Leaf XA"));        composite.Add(new Leaf("Leaf XB"));        root.Add(composite);//枝节点Compostie X上放了两个叶子节点        Composite composite2=new Composite("Composite XY");        composite2.Add(new Leaf("Leaf XYA"));        composite2.Add(new Leaf("Leaf XYB"));        composite.Add(composite2);//将枝节点Composite XY放到枝节点Composite X上        root.Add(new Leaf("Leaf C"));        Leaf leaf=new Leaf("Leaf D");        root.Add(leaf);        root.Remove(leaf);        root.Display(1);    }}

结果:
这里写图片描述

三、实例之公司管理系统

类图
这里写图片描述

//抽象公司类public abstract class Company {    protected String name;    public Company(String name){        this.name=name;    }    public abstract void Add(Company c);//添加    public abstract void Remove(Company c);//移除    public abstract void Display(int dept);//展示    public abstract void LineOfDuty();//履行职责}
//具体公司public class ConcreteCompany extends Company{    private List<Company> list=new ArrayList<>();    public ConcreteCompany(String name) {        super(name);    }    @Override    public void Add(Company c) {        list.add(c);    }    @Override    public void Remove(Company c) {        list.remove(c);    }    @Override    public void Display(int dept) {        String string="";        for(int i=0;i<dept;i++){            string+="-";        }        System.out.println(string+name);        for(Company company:list){            company.Display(dept+2);        }    }    @Override    public void LineOfDuty() {    }}
//人力资源部public class HRDepartment extends Company{    public HRDepartment(String name) {        super(name);    }    @Override    public void Add(Company c) {        System.out.println("不能操作");    }    @Override    public void Remove(Company c) {        System.out.println("不能操作");    }    @Override    public void Display(int dept) {        String string="";        for(int i=0;i<dept;i++){            string+="-";        }        System.out.println(string+name);    }    @Override    public void LineOfDuty() {        System.out.println("员工招聘管理"+name);    }}//财务部class FinanceDepartment extends Company{    public FinanceDepartment(String name) {        super(name);    }    @Override    public void Add(Company c) {        System.out.println("不能操作");    }    @Override    public void Remove(Company c) {        System.out.println("不能操作");    }    @Override    public void Display(int dept) {        String string="";        for(int i=0;i<dept;i++){            string+="-";        }        System.out.println(string+name);    }    @Override    public void LineOfDuty() {        System.out.println("公司财务管理"+name);    }}
//客户端public class Show {    public static void main(String[] args) {        ConcreteCompany root=new ConcreteCompany("总公司");        root.Add(new HRDepartment("总公司人力资源部"));        root.Add(new FinanceDepartment("总公司财务部门"));        ConcreteCompany company=new ConcreteCompany("分公司1");        company.Add(new HRDepartment("分公司1人力资源部"));        company.Add(new FinanceDepartment("分公司1财务部门"));        root.Add(company);        ConcreteCompany company2=new ConcreteCompany("分公司1");        company2.Add(new HRDepartment("分公司1人力资源部"));        company2.Add(new FinanceDepartment("分公司1财务部门"));        root.Add(company2);        ConcreteCompany company3=new ConcreteCompany("分公司1");        company3.Add(new HRDepartment("分公司1人力资源部"));        company3.Add(new FinanceDepartment("分公司1财务部门"));        root.Add(company3);        root.Display(1);    }}

结果:
这里写图片描述

四、总结

(1)、通过使用组合模式,可以解决整体与部分被一致对待的问题,如公司管理系统实例中,通过组合模式使得子公司和总公司一样都具有财务部,人力资源部这两部分。
(2)、组合模式有透明方式和安全方式两种,上述采用的是透明方式,所谓透明方式就是Leaf叶子节点和Composite枝节点具有完全一致的行为接口,但实际上Leaf叶子节点不应该有Add(),Remove()这样的方法的,因此在叶子节点中实现了这两个方法是完全没有意义的。而安全方式就是不在Component中声明Add(),Remove()这样的方法,但是在客户端调用时需要相应的判断(区分叶子节点和枝节点),如果是实现了相同接口的话,就不用这么麻烦了。

I know someone in the world is waiting for me, although I’ve no idea of who he is. But I feel happy every day for this.

原创粉丝点击