大话设计模式之组合模式总结-java实现

注:示例来自《大话设计模式》

假如现有如下场景 给一家大公司做办公管理系统 总部有人力资源 财务 运营等部门 还有一些分公司 现在有个需求 总公司的人力资源部 财务部等办公管理功能在所有的分公司都需要有 这其实就是整体与部分可以被一致对待的问题 下面我们使用组合模式进行简单实现 代码如下

公司类

package Test19;

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 depth);//显示
    public abstract void LineOfDuty();//履行职责

}

具体公司类

package Test19;

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

import org.apache.commons.lang.StringUtils;

public class ConcreteCompany extends Company {

    private List<Company> children = new ArrayList<Company>();

    public ConcreteCompany(String name) {
        super(name);

    }

    @Override
    public void Add(Company c) {
        children.add(c);

    }

    @Override
    public void Remove(Company c) {
        children.remove(c);

    }

    @Override
    public void Display(int depth) {
        System.out.println(StringUtils.repeat("-", depth) + name);

        for (Company component : children)
        {
            component.Display(depth + 2);
        }

    }

    @Override
    public void LineOfDuty() {

        for (Company component : children)
        {
            component.LineOfDuty();
        }

    }

}

人力资源部与财务部类

package Test19;

import org.apache.commons.lang.StringUtils;

//人力资源部
public class HRDepartment extends Company {

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

    }

    @Override
    public void Add(Company c) {


    }

    @Override
    public void Remove(Company c) {


    }

    @Override
    public void Display(int depth) {
        System.out.println(StringUtils.repeat("-", depth) + name);

    }

    @Override
    public void LineOfDuty() {
        System.out.println(name+" 员工招聘培训管理");

    }

}
package Test19;

import org.apache.commons.lang.StringUtils;

//财务部
public class FinanceDepartment extends Company {

    public FinanceDepartment(String name) {
        super(name);

    }

    @Override
    public void Add(Company c) {


    }

    @Override
    public void Remove(Company c) {


    }

    @Override
    public void Display(int depth) {
        System.out.println(StringUtils.repeat("-", depth) + name);

    }

    @Override
    public void LineOfDuty() {
        System.out.println(name+" 公司财务收支管理");

    }

}

客户端代码

package Test19;

public class Program {

    public static void main(String[] args) {

        ConcreteCompany root = new ConcreteCompany("北京总公司");
        root.Add(new HRDepartment("总公司人力资源部"));
        root.Add(new FinanceDepartment("总公司财务部"));

        ConcreteCompany comp = new ConcreteCompany("上海华东分公司");
        comp.Add(new HRDepartment("华东分公司人力资源部"));
        comp.Add(new FinanceDepartment("华东分公司财务部"));
        root.Add(comp);

        ConcreteCompany comp1 = new ConcreteCompany("南京办事处");
        comp1.Add(new HRDepartment("南京办事处人力资源部"));
        comp1.Add(new FinanceDepartment("南京办事处财务部"));
        comp.Add(comp1);

        ConcreteCompany comp2 = new ConcreteCompany("杭州办事处");
        comp2.Add(new HRDepartment("杭州办事处人力资源部"));
        comp2.Add(new FinanceDepartment("杭州办事处财务部"));
        comp.Add(comp2);


        System.out.println("\n结构图:");

        root.Display(1);

        System.out.println("\n职责:");

        root.LineOfDuty();

    }

}

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

透明方式 也就是说在Component中声明所有用来管理子对象的方法 其中包括Add Remove等 这样实现Component接口的所有子类都具备了Add Remove 这样做的好处就是叶节点和枝节点对于外界没有区别 它们具备完全一致的行为接口 但问题也很明显 因为叶节点类本身不具备Add() Remove()方法的功能 所以实现它是没有意义的

安全方式 也就是在Component接口中不去声明Add和Remove方法 那么子类的叶节点也就不需要去实现它 而是在枝节点声明所有用来管理子类对象的方法 不过由于不够透明 所以树叶和树枝类将不具有相同的接口 客户端的调用需要做相应的判断 带来了不便

当你发现需求中是体现部分与整体层次的结构时 以及你希望用户可以忽略组合对象与单个对象的不同 统一地使用组合结构中的所有对象时 就应该考虑用组合模式了

组合模式定义了包含人力资源部和财务部这些基本对象和分公司等组合对象的类层次结构 基本对象可以被组合成更复杂的组合对象 而这个组合对象又可以被组合 这样不断地递归下去 客户代码中 任何用到基本对象的地方都可以使用组合对象了 用户是不用关系到底是处理一个叶节点还是处理一个组合组件 也就用不着为定义组合而写一些选择判断语句了 组合模式让客户可以一致地使用组合结构和单个对象

猜你喜欢

转载自blog.csdn.net/qq_26814945/article/details/82453676