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

今天来介绍一种新的设计模式:组合模式。

当我们想要实现有层次的结构,比如公司结构,或者学校结构等,它们的层次结构很像数据结构的树,今天介绍的这个设计模式也就是实现这个数据结构的。

模板:

接口:

/**
 * @author 陈柏宇
 * 组合模式,适合有层次的结构使用,典型的树形结构。
 */

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 show(int depth);
}

叶节点:

public class Leaf extends Component{
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        System.out.println("叶节点无法添加子节点");
    }

    @Override
    public void remove(Component component) {
        System.out.println("叶节点没有子节点");
    }

    @Override
    public void show(int depth) {
        StringBuffer buffer = new StringBuffer(depth);
        for (int i=0;i<depth;i++)
            buffer.append('-');
        System.out.println(buffer + name);
    }
}

子树节点:

public class Composite extends Component{
    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 show(int depth) {
        StringBuffer buffer = new StringBuffer(depth);
        for (int i=0;i<depth;i++)
            buffer.append('-');
        System.out.println(buffer + name);

        for (Component component : list) {
            component.show(depth + 2);
        }
    }
}

客户端代码:

public static void main(String[] args) {
    Component root = new Composite("root");
    root.add(new Leaf("Leaf A"));
    root.add(new Leaf("Leaf B"));
    
   Component comp
= new Composite("Composite X"); comp.add(new Leaf("Leaf XA")); comp.add(new Leaf("Leaf XB")); root.add(comp); Component comp2 = new Composite("Composite XY"); comp2.add(new Leaf("Leaf XYA")); comp2.add(new Leaf("Leaf XYB")); comp.add(comp2); root.add(new Leaf("Leaf C")); Leaf leaf = new Leaf("Leaf D"); root.add(leaf); root.remove(leaf); root.show(1); }

控制台输出:

-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
-----Composite XY
-------Leaf XYA
-------Leaf XYB
---Leaf C

现在我来举一个具体的例子:
我的大学是南京林业大学,大学前两年我是在淮安校区度过的,于是淮安校区就可以看作是南京林业大学的一个子校区,而南京林业大学本身又有很多学院,学院底下也分很多专业,

所以这就是一个很典型的树形结构。

代码:
抽象类,学术机构类:

public abstract class Academy {
    protected String name;

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

    //增加子校区或者学院
    public abstract void add(Academy university);

    //删除子校区或者学院
    public abstract void remove(Academy university);

    //展示自己和子节点
    public abstract void display(int depth);

    //履行职责
    public abstract void duty();
}

大学类,实现学术机构接口

/**
 * @author 陈柏宇
 * 大学类,子节点是分校区或者学院
 */

public class University extends Academy {

    List<Academy> list = new ArrayList<>();

    public University(String name) {
        super(name);
    }

    @Override
    public void add(Academy academy) {
        list.add(academy);
    }

    @Override
    public void remove(Academy academy) {
        list.remove(academy);
    }

    @Override
    public void display(int depth) {
        StringBuffer buffer = new StringBuffer(depth);
        for (int i=0;i<depth;i++)
            buffer.append('-');
        System.out.println(buffer + name);
        for (Academy academy : list) {
            academy.display(depth + 2);
        }
    }

    @Override
    public void duty() {
        System.out.println(name + "大学,负责管理学院。");
        for (Academy academy : list) {
            academy.duty();
        }
    }
}

学院类:

/**
 * @author 陈柏宇
 * 学院类,子类是专业类
 */

public class College extends Academy{
    List<Academy> majors = new ArrayList<>();

    public College(String name) {
        super(name);
    }

    @Override
    public void add(Academy academy) {
        majors.add(academy);
    }

    @Override
    public void remove(Academy academy) {
        majors.remove(academy);
    }

    @Override
    public void display(int depth) {
        StringBuffer buffer = new StringBuffer(depth);
        for (int i=0;i<depth;i++)
            buffer.append('-');
        System.out.println(buffer + name );
        for (Academy major : majors) {
            major.display(depth + 2);
        }
    }

    @Override
    public void duty() {
        System.out.println(name + "学院,负责管理各专业。");
        for (Academy major : majors) {
            major.duty();
        }
    }
}

专业类:叶节点

/**
 * @author 陈柏宇
 * 专业类
 */

public class Major extends Academy{
    public Major(String name) {
        super(name);
    }

    @Override
    public void add(Academy university) {
        System.out.println("专业无法再分类了!");
    }

    @Override
    public void remove(Academy university) {
        System.out.println("专业无法删除分类了!");
    }

    @Override
    public void display(int depth) {
        StringBuffer buffer = new StringBuffer(depth);
        for (int i=0;i<depth;i++)
            buffer.append('-');
        System.out.println(buffer + name);
    }

    @Override
    public void duty() {
        System.out.println(name + "专业,负责专业人才培养。");
    }
}

客户端代码:

public static void main(String[] args) {
        Academy NJFU = new University("南京林业大学本部");
        Academy NjfuHuai = new University("南京林业大学淮安校区");
        NJFU.add(NjfuHuai);

        Academy ComputerScience = new College("本部计算机学院");
        ComputerScience.add(new Major("本部软件工程专业"));
        ComputerScience.add(new Major("本部计算机科学专业"));

        Academy Mechanics = new College("本部机械电子工程学院");
        Mechanics.add(new Major("本部机电专业"));
        Mechanics.add(new Major("本部机械设计制造专业"));

        NJFU.add(ComputerScience);
        NJFU.add(Mechanics);

        Academy ComputerScienceHuai = new College("淮安校区计算机学院");
        ComputerScienceHuai.add(new Major("淮安校区软件工程专业"));
        ComputerScienceHuai.add(new Major("淮安校区计算机科学专业"));

        Academy MechanicsHuai = new College("淮安校区机械电子工程学院");
        MechanicsHuai.add(new Major("淮安校区机电专业"));
        MechanicsHuai.add(new Major("淮安校区机械设计制造专业"));

        NjfuHuai.add(ComputerScienceHuai);
        NjfuHuai.add(MechanicsHuai);

        NJFU.display(1);

        System.out.println("***********************职责********************");
        NJFU.duty();
    }

控制台输出:

-南京林业大学本部
---南京林业大学淮安校区
-----淮安校区计算机学院
-------淮安校区软件工程专业
-------淮安校区计算机科学专业
-----淮安校区机械电子工程学院
-------淮安校区机电专业
-------淮安校区机械设计制造专业
---本部计算机学院
-----本部软件工程专业
-----本部计算机科学专业
---本部机械电子工程学院
-----本部机电专业
-----本部机械设计制造专业
***********************职责********************
南京林业大学本部大学,负责管理学院。
南京林业大学淮安校区大学,负责管理学院。
淮安校区计算机学院学院,负责管理各专业。
淮安校区软件工程专业专业,负责专业人才培养。
淮安校区计算机科学专业专业,负责专业人才培养。
淮安校区机械电子工程学院学院,负责管理各专业。
淮安校区机电专业专业,负责专业人才培养。
淮安校区机械设计制造专业专业,负责专业人才培养。
本部计算机学院学院,负责管理各专业。
本部软件工程专业专业,负责专业人才培养。
本部计算机科学专业专业,负责专业人才培养。
本部机械电子工程学院学院,负责管理各专业。
本部机电专业专业,负责专业人才培养。
本部机械设计制造专业专业,负责专业人才培养。

其中组合模式也分为透明模式和安全模式。

透明模式是指无论你是叶节点还是子树节点你都可以执行add和remove操作。

而安全模式则在接口中不写add()和remove()方法,只在子树结构中写。

两者的使用视情况而定。

 

posted @ 2021-09-22 23:13  Apak陈柏宇  阅读(99)  评论(0编辑  收藏  举报