一、组合模式概念

组合模式:(整体与部分关系)将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 "组合对象" 的含义。

涉及角色: 

  • 1.Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
  • 2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
  • 3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

 二、组合模式通用类图

 component (抽象构件:容器):它可以是接口或者抽象类,为叶子构建和子容器构建对象声明接口,在该角色中可以包含所有子类共有的行为的实现和声明。在抽象构建中定义了访问及管理它的子构件的方法,如增加子构件,删除子构件,获取子构件等。

leaf(叶子构建):叶子构建可以说就是各种类型的文件!叶子构建没有子构件。它实现了抽象构建中的定义的行为。对于那些访问子容器,删除子容器,增加子容器的就报错。

compsite(子容器构建):它在组合模式中表示容器节点对象,容器结点是子节点,可以是子容器,也可以是叶子构建,它提供一个集合来存储子节点。

首先写抽象构件:

package com.ssy.wlj.composite2;

/**
 * 抽象构件
 * 
 * @author Administrator
 * @since 2019/05/23
 *
 */
public abstract class Component {
    protected String name;

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

    public Component() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 这个是容器类的抽象类,定义好行为,定义创建移除子容器的方法抽象的。
    public abstract void addComposite(Component c); // 添加成员

    public abstract void removeComposite(Component c);// 移除成员

    public abstract Component getComposite(int i);// 获取子容器

    public abstract void operation(int depth);// 业务方法
}

写子容器构件:

package com.ssy.wlj.composite2;

import java.util.ArrayList;

/**
 * 子容器构建
 * 
 * @author Administrator
 * @since 2019/05/23
 *
 */
public class Composite extends Component {

    // 首先来一个存储的集合
    private ArrayList<Component> list;

    public Composite(String name) {
        super(name);
        list = new ArrayList<Component>();
    }

    public Composite() {
        list = new ArrayList<Component>();
    }

    @Override
    public void addComposite(Component c) {
        list.add(c);
    }

    @Override
    public void removeComposite(Component c) {
        list.remove(c);
    }

    @Override
    public Component getComposite(int c) {
        Component c1 = list.get(c);
        return c1;
    }

    @Override
    public void operation(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.getName());
        for (Component c : list) {
            c.operation(depth + 2);
        }
    }

}

叶子构件:

package com.ssy.wlj.composite2;

/**
 * 叶子构建
 * 
 * @author Administrator
 * @since 2019/05/23
 *
 */
public class Leaf extends Component {

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

    // 首先重写component的方法
    // 叶子节点关键点在于业务
    @Override
    public void operation(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.getName());
    }

    public Component addComponent(int c) {
        System.out.print("不是子容器");
        return null;
    }

    @Override
    public void addComposite(Component c) {
        System.out.print("不是子容器");
    }

    @Override
    public void removeComposite(Component c) {
        System.out.print("不是子容器");
    }

    @Override
    public Component getComposite(int i) {
        System.out.print("不是子容器");
        return null;
    }
}

最后写个测试类:

package com.ssy.wlj.composite2;

public class Client {
    public static void main(String[] args) {
        Component root = new Composite("zs");
        root.addComposite(new Leaf("a"));
        root.addComposite(new Leaf("b"));
        Component file = new Composite("ls");
        file.addComposite(new Leaf("c"));
        file.addComposite(new Leaf("d"));
        root.addComposite(file);
        root.operation(1);        
    }
}

三、组合模式场景展示

  这里以公司的组织机构为例,公司分为人力资源部、财务部等。

类图如下:

首先创建公司抽象类:

package com.ssy.wlj.composite;

/**
 *   抽象接口类:用来管理子类
 * @author Administrator
 * @since 2019/05/23
 *
 */
public abstract class Company {
    // 公司名称
    private String name;
    public Company(String name) {
        super();
        this.name = name;
    }
    public Company() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    // 添加公司如:新增分公司
    protected abstract void add(Company company);
    // 删除公司:如因故关闭分公司
    protected abstract void romove(Company company);
    //显示公司所在的层级:总公司,分公司,办事处等
    protected abstract void display(int depth);

}

创建分公司类:

package com.ssy.wlj.composite;

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

/**
 *   分公司对象
 * @author Administrator
 * @since 2019/05/23
 *
 */
public class ConcreteCompany extends Company {

    private List<Company> cList;
    public ConcreteCompany() {
        cList = new ArrayList();
    }
    public ConcreteCompany(String name) {
        super(name);
        cList = new ArrayList();
    }
    @Override
    protected void add(Company company) {
        cList.add(company);
    }
    @Override
    protected void display(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.getName());
        for (Company c : cList) {
            c.display(depth + 2);
        }
    }
    @Override
    protected void romove(Company company) {
        cList.remove(company);
    }
}

创建Leaf节点:公司人力资源部门

package com.ssy.wlj.composite;

/**
 * Leaf结点类:公司人力资源部门
 * @author Administrator
 * @since 2019/05/23
 *
 */
public class HRDepartment extends Company {

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

    @Override
    protected void add(Company company) {
    }

    @Override
    protected void display(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.getName());
    }

    @Override
    protected void romove(Company company) {
    }

}

创建Leaf节点:公司财务部门

package com.ssy.wlj.composite;

/**
 * Leaf结点类:公司财务部门
 * @author Administrator
 * @since 2019/05/23
 *
 */
public class FinanceDepartment extends Company {
    public FinanceDepartment(String name) {
        super(name);
    }

    @Override
    protected void add(Company company) {
    }

    @Override
    protected void display(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.getName());
    }

    @Override
    protected void romove(Company company) {
    }
}

最后编写测试类:

package com.ssy.wlj.composite;

public class Client {
    public static void main(String[] args) {
        Company root = new ConcreteCompany();
        root.setName("北京总公司");
        root.add(new HRDepartment("总公司人力资源部"));
        root.add(new FinanceDepartment("总公司财务部"));
        Company shandongCom = new ConcreteCompany("山东分公司");
        shandongCom.add(new HRDepartment("山东分公司人力资源部"));
        shandongCom.add(new FinanceDepartment("山东分公司账务部"));
        Company zaozhuangCom = new ConcreteCompany("枣庄办事处");
        zaozhuangCom.add(new FinanceDepartment("枣庄办事处财务部"));
        zaozhuangCom.add(new HRDepartment("枣庄办事处人力资源部"));
        Company jinanCom = new ConcreteCompany("济南办事处");
        jinanCom.add(new FinanceDepartment("济南办事处财务部"));
        jinanCom.add(new HRDepartment("济南办事处人力资源部"));
        shandongCom.add(jinanCom);
        shandongCom.add(zaozhuangCom);
        Company huadongCom = new ConcreteCompany("上海华东分公司");
        huadongCom.add(new HRDepartment("上海华东分公司人力资源部"));
        huadongCom.add(new FinanceDepartment("上海华东分公司账务部"));
        Company hangzhouCom = new ConcreteCompany("杭州办事处");
        hangzhouCom.add(new FinanceDepartment("杭州办事处财务部"));
        hangzhouCom.add(new HRDepartment("杭州办事处人力资源部"));
        Company nanjingCom = new ConcreteCompany("南京办事处");
        nanjingCom.add(new FinanceDepartment("南京办事处财务部"));
        nanjingCom.add(new HRDepartment("南京办事处人力资源部"));
        huadongCom.add(hangzhouCom);
        huadongCom.add(nanjingCom);
        root.add(shandongCom);
        root.add(huadongCom);
        //如果还需要新增分公司或办事处等,就继续按照上述操作处理
        root.display(0);
    }
}

运行测试效果:

北京总公司
--总公司人力资源部
--总公司财务部
--山东分公司
----山东分公司人力资源部
----山东分公司账务部
----济南办事处
------济南办事处财务部
------济南办事处人力资源部
----枣庄办事处
------枣庄办事处财务部
------枣庄办事处人力资源部
--上海华东分公司
----上海华东分公司人力资源部
----上海华东分公司账务部
----杭州办事处
------杭州办事处财务部
------杭州办事处人力资源部
----南京办事处
------南京办事处财务部
------南京办事处人力资源部

 

posted on 2019-05-23 15:10  happy_2010  阅读(154)  评论(0编辑  收藏  举报