组合模式____设计模式学习笔记

组合模式

UML结构图

这里写图片描述

范例

/**
 *  为组合的对象声明接口,在适当的情况下,实现所有类共有接口的默认行.
 *  声明一个接口用于访问和管理Component的子部件.
 */
public abstract class Component {
    public String name;

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

    public abstract void add(Component component);
    public abstract void remove(Component component);
    public abstract void desplay(int depth);

    @Override
    public String toString() {
        return "Component{" +
                "name='" + name + '\'' +
                '}';
    }

    protected String getDepthString(int depth){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i <depth ; i++) {
            sb.append("-");
        }
        return sb.toString();
    }
}
/**
 * 定义直节点行为,用来存储子部件
 * 实现Component接口定义的子部件有关的行为,如add remove
 */
public class Composite extends Component{
    private List<Component> mComponents=new ArrayList<>();

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

    @Override
    public void add(Component component) {
        mComponents.add(component);
    }

    @Override
    public void remove(Component component) {
        mComponents.remove(component);
    }

    @Override
    public void desplay(int depth) {
        Log.d("meee", getDepthString(depth)+name);
        for(Component component:mComponents){
            component.desplay(depth+2);
        }
    }
}
/**
 * 在组合中表示叶节点,没有子节点
 */
public class Leaf extends Component{
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        Log.d("meee", "cannot add to a leaf");
    }

    @Override
    public void remove(Component component) {
        Log.d("meee", "cannot remove from a leaf");
    }

    @Override
    public void desplay(int depth) {
        Log.d("meee", ""+getDepthString(depth)+name);
    }
}
//客户端调用
        Component root=new Composite("root");
        root.add(new Leaf("根叶子1"));
        root.add(new Leaf("根叶子2"));

        Component component1=new Composite("分支1");
        component1.add(new Leaf("分支1叶子1"));
        component1.add(new Leaf("分支1叶子2"));
        root.add(component1);

        Component component2=new Composite("分支2");
        component2.add(new Leaf("分支2叶子1"));
        component2.add(new Leaf("分支2叶子2"));
        Composite 分支2的分支 = new Composite("分支2的分支");
        分支2的分支.add(new Leaf("分支2的分支的叶子1"));
        分支2的分支.add(new Leaf("分支2的分支的叶子2"));
        分支2的分支.add(new Leaf("分支2的分支的叶子3"));
        component2.add(分支2的分支);
        root.add(component2);

        Leaf removeLeaf = new Leaf("被风吹走的叶子");
        root.add(removeLeaf);
        root.remove(removeLeaf);

        root.desplay(1);
04-10 14:51:08.446 28647-28647/? D/meee: -root
04-10 14:51:08.446 28647-28647/? D/meee: ---根叶子1
04-10 14:51:08.446 28647-28647/? D/meee: ---根叶子2
04-10 14:51:08.446 28647-28647/? D/meee: ---分支1
04-10 14:51:08.446 28647-28647/? D/meee: -----分支1叶子1
04-10 14:51:08.446 28647-28647/? D/meee: -----分支1叶子2
04-10 14:51:08.446 28647-28647/? D/meee: ---分支2
04-10 14:51:08.447 28647-28647/? D/meee: -----分支2叶子1
04-10 14:51:08.447 28647-28647/? D/meee: -----分支2叶子2
04-10 14:51:08.447 28647-28647/? D/meee: -----分支2的分支
04-10 14:51:08.447 28647-28647/? D/meee: -------分支2的分支的叶子1
04-10 14:51:08.447 28647-28647/? D/meee: -------分支2的分支的叶子2
04-10 14:51:08.447 28647-28647/? D/meee: -------分支2的分支的叶子3

组合模式的两种实现方式

    /**
     * 组合模式的两种实现方式:
     *      1.透明方式
     *          实现Component接口的所有子类都具备了add() remove().
     *          好处是叶子节点和枝节点对于外部而言没有区别,他们具备完全相同的接口
     *          坏处是叶子节点的add() remove()实际是没有意义的
     *      2.安全方式
     *          在Component接口中不声明add() remove()方法
     *          好处是安全
     *          坏处是客户端需要负担对不同的类型进行判断
     */

公司管理系统范例

这里写图片描述

public abstract class Company {
    protected String name;
    public Company(String name) {
        this.name = name;
    }
    public abstract void remove(Company company);
    public abstract void add(Company company);
    public abstract void display(int depth);
    //履行不同的职责
    public abstract void lineDuty();

    protected String getDepthString(int depth){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i <depth ; i++) {
            sb.append("-");
        }
        return sb.toString();
    }
}
public class ConcreteCompany extends Company {
    private List<Company> mCompanies=new ArrayList<>();

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

    @Override
    public void remove(Company company) {
        mCompanies.add(company);
    }

    @Override
    public void add(Company company) {
        mCompanies.add(company);
    }

    @Override
    public void display(int depth) {
        Log.d("meee", getDepthString(depth)+"|"+name);
        for (Company company:mCompanies){
            company.display(depth+2);
        }
    }

    @Override
    public void lineDuty() {
        Log.d("meee", name+"号召好好工作");
        for (Company company:mCompanies){
            company.lineDuty();
        }
    }
}
public class FinanceDepatrment extends Company{
    public FinanceDepatrment(String name) {
        super(name);
    }

    @Override
    public void remove(Company company) {

    }
    @Override
    public void add(Company company) {

    }

    @Override
    public void display(int depth) {
        Log.d("meee", getDepthString(depth)+"|"+name);
    }

    @Override
    public void lineDuty() {
        Log.d("meee", name+"开始计算公司的收人和支出");
    }
}
public class HrDepartment extends Company {
    public HrDepartment(String name) {
        super(name);
    }

    @Override
    public void remove(Company company) {

    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void display(int depth) {
        Log.d("meee", getDepthString(depth)+"|"+name);
    }

    @Override
    public void lineDuty() {
        Log.d("meee", name+"的HR开始招人");
    }
}
//客户端代码
        Company mainCompany=new ConcreteCompany("母公司");
        mainCompany.add(new FinanceDepatrment("总公司财务部"));
        mainCompany.add(new HrDepartment("总公司人力资源部"));

        Company GdCompany=new ConcreteCompany("广东分公司");
        GdCompany.add(new HrDepartment("广东分公司人力资源部"));
        GdCompany.add(new FinanceDepatrment("广东分公司财务部"));
        mainCompany.add(GdCompany);

        Company ShCompany=new ConcreteCompany("上海分公司");
        ShCompany.add(new HrDepartment("上海分公司人力资源部"));
        ShCompany.add(new FinanceDepatrment("上海分公司财务部"));
        mainCompany.add(ShCompany);

        Company BgCompany=new ConcreteCompany("北京分公司");
        BgCompany.add(new HrDepartment("北京分公司人力资源部"));
        BgCompany.add(new FinanceDepatrment("北京分公司财务部"));
        mainCompany.add(BgCompany);

        mainCompany.display(1);
        mainCompany.lineDuty();
04-10 15:31:33.281 30620-30620/? D/meee: -|母公司
04-10 15:31:33.281 30620-30620/? D/meee: ---|总公司财务部
04-10 15:31:33.281 30620-30620/? D/meee: ---|总公司人力资源部
04-10 15:31:33.281 30620-30620/? D/meee: ---|广东分公司
04-10 15:31:33.281 30620-30620/? D/meee: -----|广东分公司人力资源部
04-10 15:31:33.281 30620-30620/? D/meee: -----|广东分公司财务部
04-10 15:31:33.281 30620-30620/? D/meee: ---|上海分公司
04-10 15:31:33.282 30620-30620/? D/meee: -----|上海分公司人力资源部
04-10 15:31:33.282 30620-30620/? D/meee: -----|上海分公司财务部
04-10 15:31:33.282 30620-30620/? D/meee: ---|北京分公司
04-10 15:31:33.282 30620-30620/? D/meee: -----|北京分公司人力资源部
04-10 15:31:33.282 30620-30620/? D/meee: -----|北京分公司财务部
04-10 15:31:33.282 30620-30620/? D/meee: 母公司号召好好工作
04-10 15:31:33.282 30620-30620/? D/meee: 总公司财务部开始计算公司的收人和支出
04-10 15:31:33.282 30620-30620/? D/meee: 总公司人力资源部的HR开始招人
04-10 15:31:33.282 30620-30620/? D/meee: 广东分公司号召好好工作
04-10 15:31:33.282 30620-30620/? D/meee: 广东分公司人力资源部的HR开始招人
04-10 15:31:33.282 30620-30620/? D/meee: 广东分公司财务部开始计算公司的收人和支出
04-10 15:31:33.282 30620-30620/? D/meee: 上海分公司号召好好工作
04-10 15:31:33.282 30620-30620/? D/meee: 上海分公司人力资源部的HR开始招人
04-10 15:31:33.282 30620-30620/? D/meee: 上海分公司财务部开始计算公司的收人和支出
04-10 15:31:33.282 30620-30620/? D/meee: 北京分公司号召好好工作
04-10 15:31:33.282 30620-30620/? D/meee: 北京分公司人力资源部的HR开始招人
04-10 15:31:33.282 30620-30620/? D/meee: 北京分公司财务部开始计算公司的收人和支出
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值