设计模式之组合模式

什么是组合模式

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

原理类图

在这里插入图片描述

为什么要用组合模式

今年学校的创新创业大赛结果非常好啊,计算机学院有一组学生做出来一份非常好的作品。这个产品可以提供一个非常高效的师生信息流通的渠道。学院打算加以应用并推广。

为了保证这产品确实可用,不会推出后学生没法用,学院不好处理。学院打算先在学院内部使用一下:

计算机学院:

public class ITAcademy {
    public void useProduct() {
        System.out.println("计算机学院使用产品");
    }
}

使用产品:

public class Main {
    public static void main(String[] args) {
        ITAcademy IT = new ITAcademy();
        IT.useProduct();
    }
}

非常好,这个产品可以使用。

那么,推广吧,给学校过过眼。

学校综合考虑之后,决定使用并通知各学院和独立学院也可以使用这款产品。

注:独立学院是一个学校,比如浙江大学宁波理工学院


但是,怎么给学校呢?

  1. 直接把代码复制给学校一份

    • 这样确实可以使用,但是学校与学院和独立学院的关系就不那么紧密了
  2. 让各学院继承计算机学院

    • 这样也是一种办法,但是让学校继承计算机学院,似乎有些不妥;同样的,其他学院和计算机学院应该是平级的,直接继承确实不妥
  3. 把学校作为根,让各学院继承学校

    • 这样似乎没什么问题了,各部分之间的关系有了,同时还有了继承关系;
    • 但是,独立学院怎么办?独立学院作为一个独立的学校,下面也有很多学院,让那些独立学院的学院也继承这个学校吗?不妥把,那独立学院的计算机学院岂不是和独立学院平级了。
  4. 应用组合模式,把各个学院组合进学校里面,同时把独立学院也组合进学校里面,独立学院也可以组合其下属的各个学院。

那么,用组合模式实现一下吧:

首先有一个抽象的学校(Component):

public abstract class AbstractUniversity {
    protected String name;

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

    public abstract void add(AbstractUniversity abstractUniversity);

    public abstract void remove(AbstractUniversity abstractUniversity);

    public abstract void useProduct(int depth);
}

学校的具体实现(Composite):

public class University extends AbstractUniversity {
    private List<AbstractUniversity> academies = new ArrayList<>();

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

    @Override
    public void add(AbstractUniversity abstractUniversity) {
        academies.add(abstractUniversity);
    }

    @Override
    public void remove(AbstractUniversity abstractUniversity) {
        academies.remove(abstractUniversity);
    }

    @Override
    public void useProduct(int depth) {
        System.out.println(name + "使用产品,层级:" + depth);
        for (AbstractUniversity abstractUniversity : academies) {
            abstractUniversity.useProduct(depth + 1);
        }
    }
}

学院(Leaf):

public class Academy extends AbstractUniversity {

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

    @Override
    public void add(AbstractUniversity abstractUniversity) {
        System.out.println(name + "没有下属学院,无法添加");
    }

    @Override
    public void remove(AbstractUniversity abstractUniversity) {
        System.out.println(name + "没有下属学院,无法删除");
    }

    @Override
    public void useProduct(int depth) {
        System.out.println(name + "使用产品,层级:" + depth);
    }
}

最后模拟一下:

public class Main {
    public static void main(String[] args) {
        University university = new University("学校本部");
        University college = new University("独立学院");

        university.add(new Academy("本部计算机学院"));
        university.add(new Academy("本部物理学院"));
        university.add(college);
        college.add(new Academy("独立学院计算机学院"));
        college.add(new Academy("独立学院物理学院"));

        university.useProduct(1);
    }
}

输出结果:

学校本部使用产品,层级:1
本部计算机学院使用产品,层级:2
本部物理学院使用产品,层级:2
独立学院使用产品,层级:2
独立学院计算机学院使用产品,层级:3
独立学院物理学院使用产品,层级:3

这样,这个产品重要可以在学校里有层级关系得使用了。

当前类图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值