君临-行者无界

导航

组合模式

  组合模式定义:将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

  组合模式设计到的角色:

  1.Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

  2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。

  3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

 

  我们经常遇到的文件系统,或者公司部门结构,产品分类等,就非常适合用组合模式来处理,下面就公司结构做个demo。先看类图

  demo如下

package com.example.demo;

public interface Element {

    String getName();
    void delete();
    void addElement(String name );

    void  deleteElement(String name);

    Element getElement(int index);

}
package com.example.demo;

import java.util.ArrayList;
import java.util.List;

public class Department implements Element{
    private String name;
    private Element superior;
    private List<Element> child;

    public Department() {
    }

    public Department(String name, Element superior) {
        this.name = name;
        this.superior = superior;
        this.child = new ArrayList<>();
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void delete() {
        List<Element> copy = new ArrayList<Element>(child);
        for (Element e:copy){
            e.delete();
        }
        if(superior != null){
            superior.deleteElement(name);
        }
    }
    @Override
    public void deleteElement(String name){
        for (Element e:child){
            if(e.getName().equals(name)){
                child.remove(e);
                break;
            }
        }
    }

    @Override
    public Element getElement(int index) {

        return child.get(index);
    }

    @Override
    public void addElement(String name ) {
        //名字中含有de的说明是一个部门
        if (name.contains("de") ){
            child.add(new Department(name,this));
        }else{
            child.add(new Member(name,this));
        }

    }
}
package com.example.demo;

public class Member implements  Element{

    private String name;
    private Element superior;

    public Member(String name, Element superior) {
        this.name = name;
        this.superior = superior;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void delete() {
        superior.deleteElement(name);
    }

    @Override
    public void addElement(String name) {

    }

    @Override
    public void deleteElement(String name) {

    }

    @Override
    public Element getElement(int index) {
        return null;
    }
}
package com.example.demo;




public class Client {

    public static void main(String[] args) {
        Element total = new Department("总公司",null);
        total.addElement("总经理");
        total.addElement("deFinance");
        total.addElement("deSales");
        Element finance = total.getElement(1);
        Element sales = total.getElement(2);
        finance.addElement("财务经理");
        finance.addElement("财务职员张三");
        sales.addElement("销售经理");
        display(null,total);
        System.out.println();
        total.getElement(0).delete();
        sales.delete();
        finance.getElement(1).delete();
        display(null,total);
        System.out.println();
        total.delete();
        display(null,total);

    }

    public static void display(String prefix,Element e){

        if(prefix ==null){
            prefix="";
        }
        System.out.println(prefix + e.getName());
        if(e instanceof  Department){
            for(int i=0;;i++){
                try {
                    if(e.getElement(i)!= null){
                        display(prefix+"--",e.getElement(i));
                    }
                } catch (Exception e1) {
                    break;
                }
            }
        }

    }
}

  执行client中main方法,结果如下:

  可以看出,通过适用组合模式,我们对公司下员工和部门的操作是一致的。组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素,如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。

  组合模式的适用场景:

  1.表示对象的部分-整体层次结构。

  2.用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

posted on 2018-12-19 10:34  请叫我西毒  阅读(248)  评论(0编辑  收藏  举报