装饰者模式与组合模式

2020-06-27  本文已影响0人  攻城老狮

装饰者模式与组合模式

参考教程:https://www.bilibili.com/video/BV1G4411c7N4
代码实现 Github:https://github.com/yaokuku123/pattern


装饰者模式

  1. 案例

星巴克咖啡订单项目(咖啡馆):

  1. 咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式 咖啡)、Decaf(无因咖啡)。

  2. 调料:Milk、Soy(豆浆)、Chocolate。

  3. 要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便。

  4. 使用OO的来计算不同种类咖啡的费用: 客户可以点单品咖啡,也可以单品咖啡+调料组合。

  1. 传统方案1
1-1592440957464.png

这样设计,会有很多类,当我们增加一个单品咖啡,或者一个新的调料, 类的数量就会倍增,就会出现类爆炸。

  1. 传统方案2
2-1592441082436.png

方案2可以控制类的数量,不至于造成很多的类。但是在增加或者删除调料种类时,代码的维护量很大。

  1. 装饰者模式

解释:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)。

  1. 代码实现
3-1592441224442.png 4-1592441287867.png
package com.yqj.pattern.decorator;
//抽象类,Component
abstract class Drink {
    private String desc;
    private float price = 0.0f;

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public abstract float cost();
}
//缓存层,抽取具体单品的共性特征
class Coffee extends Drink {

    @Override
    public float cost() {
        return this.getPrice();
    }
}
//单品咖啡1
class ShortBlack extends Coffee {
    public ShortBlack() {
        setDesc("ShortBlack");
        setPrice(5.0f);
    }
}
//单品咖啡2
class LongBlack extends Coffee {
    public LongBlack() {
        setDesc("Decaf");
        setPrice(3.0f);
    }
}
//装饰类,Decorator。其中obj为聚合的被装饰对象
class Decorator extends Drink {

    private Drink obj;

    public Decorator(Drink obj) {
        this.obj = obj;
    }
    //递归叠加计算价格
    @Override
    public float cost() {
        return super.getPrice() + obj.cost();
    }

    @Override
    public String getDesc() {
        return super.getDesc() + "&&" + obj.getDesc();
    }
}
//具体的装饰类
class Chocolate extends Decorator {

    public Chocolate(Drink obj) {
        super(obj);
        setDesc("Chocolate");
        setPrice(2.0f);
    }
}

class Milk extends Decorator {

    public Milk(Drink obj) {
        super(obj);
        setDesc("Milk");
        setPrice(1.0f);
    }
}

public class Client {
    public static void main(String[] args) {
        Drink order = new LongBlack();
        System.out.println(order.getDesc() + " " + order.cost());
        order = new Milk(order);
        System.out.println(order.getDesc() + " " + order.cost());
        order = new Chocolate(order);
        System.out.println(order.getDesc() + " " + order.cost());
        order = new Chocolate(order);
        System.out.println(order.getDesc() + " " + order.cost());
    }
}

组合模式

  1. 案例

编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系 组成,一个学校有多个学院,一个学院有多个系。如图:

5-1592443002566.png
  1. 传统方式
6.png
  1. 组合模式

解释:它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象。

运用:)组合模式解决这样的问题,当我们的要处理的对象可以生成一颗树形结构,而我们要对树上的节点和叶子进行操作时,它能够提供一致的方式,而不用考虑它是节点还是叶子

  1. 代码实现
7.png
package com.yqj.pattern.composite;

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

abstract class OrganizationComponent {
    private String name;

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

    public String getName() {
        return name;
    }

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

    public void add(OrganizationComponent organizationComponent) {
        throw new UnsupportedOperationException();
    }

    public void remove(OrganizationComponent organizationComponent) {
        throw new UnsupportedOperationException();
    }

    public abstract void print();
}

class University extends OrganizationComponent {
    private List<OrganizationComponent> colleges = new ArrayList<>();

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


    @Override
    public void add(OrganizationComponent organizationComponent) {
        colleges.add(organizationComponent);
    }

    @Override
    public void remove(OrganizationComponent organizationComponent) {
        colleges.remove(organizationComponent);
    }

    @Override
    public void print() {
        System.out.println("++++++++++"+this.getName()+"++++++++++");
        for (OrganizationComponent college : colleges) {
            college.print();
        }
    }
}

class College extends OrganizationComponent {
    private List<OrganizationComponent> departments = new ArrayList<>();

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

    @Override
    public void add(OrganizationComponent organizationComponent) {
        departments.add(organizationComponent);
    }

    @Override
    public void remove(OrganizationComponent organizationComponent) {
        departments.remove(organizationComponent);
    }

    @Override
    public void print() {
        System.out.println("++++++++++"+this.getName()+"++++++++++");
        for (OrganizationComponent department : departments) {
            department.print();
        }
    }
}

class Department extends OrganizationComponent{

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

    @Override
    public void print() {
        System.out.println(this.getName());
    }
}

public class Client {
    public static void main(String[] args) {
        //从大到小创建对象
        //创建学校
        University university = new University("首师大");
        //创建学院
        College computerCollege = new College("计算机学院");
        College chemcialCollege = new College("化学学院");
        //创建系
        Department department1 = new Department("软件工程");
        Department department2 = new Department("计算机科学与技术");
        Department department3 = new Department("通讯工程");
        Department department4 = new Department("化学师范");
        Department department5 = new Department("应用化学");
        //将系加入各学院
        computerCollege.add(department1);
        computerCollege.add(department2);
        computerCollege.add(department3);
        chemcialCollege.add(department4);
        chemcialCollege.add(department5);
        //将学院加入学校
        university.add(computerCollege);
        university.add(chemcialCollege);
        //移除一个系
        chemcialCollege.remove(department4);
        //打印
        university.print();

    }
}
  1. 小结
上一篇下一篇

猜你喜欢

热点阅读