Java-第十八部分-设计模式-装饰者模式和组合模式

256 阅读3分钟

设计模式全文

装饰者模式

  • 案例,星巴克咖啡订单,咖啡四种,调料三种,咖啡可以单点,也可以加调料,计算不同搭配方式的费用
  • Decorator,动态地将新功能附加到对象上,在对象功能扩展方面,比继承更有弹性
  • 类比,打包一个快递,需要放入不同东西 demo.png
  • Drink 顶层模块
public abstract class Drink {
    //描述
    private String des;
    private float price = 0.0f;
    //计算价格,被子类来实现
    public abstract float cost();
    public String getDes() {
        return des;
    }
    public void setDes(String des) {
        this.des = des;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
}
  • Coffee,共同父类
public class Coffee extends Drink{
    @Override
    public float cost() {
        return super.getPrice();
    }
}
  • 咖啡的具体实现
public class Espresso extends Coffee{
    public Espresso() {
        setDes("Espresso");
        setPrice(6.0F);
    }
}
  • Decorator,装饰者,负责打包过程中添加内容
public class Decorator extends Drink{
    private Drink drink;
    public Decorator(Drink drink) { //组合
        this.drink = drink;
    }
    @Override
    public float cost() {
        //调料的价格 + 被装饰者的信息
        return super.getPrice() + drink.cost();
    }

    @Override
    public String getDes() {
        //被装饰者的描述
        return super.getDes() + " - " + super.getPrice() + " && " + drink.getDes();
    }
}
  • Milk,装饰者的具体实现
public class Milk extends Decorator{
    public Milk(Drink drink) {
        super(drink);
        setDes("Milk");
        setPrice(2.0F);
    }
}
  • 具体应用 image.png

IO源码

  • FilterInputStream就是一个装饰者 demo1.png
  • 内嵌了顶层模块,组合了被装饰者 image.png
  • 使用 image.png

组合模式

  • 案例,学校院系,学校有多个学院,学院有多个系
  • 要体现管理的关系,把学校、院、系看作组织结构,是一个树形结构
  • Composite Pattern,部分整体模式,结构型模式,创建对象组的树形结构,将对象组合成树状结构以整体-部分的层次关系
  • 组合能让客户以一致性的方式处理个别对象以及组合对象
  • 适用于要处理的对象可以生成一颗树形结构,而对树上的节点进行操作的时候,可以提供一致的方式,不用考虑具体是什么
  • 类图 demo.png
  • OrganizationComponent,抽象类,抽出组织共有的特点
public abstract class OrganizationComponent {
    private String name;
    private String des;
    //有一些类不需要add方法,通过默认实现
    protected void add(OrganizationComponent oc) {
        //如果不重写,就不支持操作
        throw new UnsupportedOperationException();
    }
    protected void remove(OrganizationComponent oc) {
        //如果不重写,就不支持操作
        throw new UnsupportedOperationException();
    }
    protected abstract void show();
    public OrganizationComponent(String name, String des) {
        this.name = name;
        this.des = des;
    }
}
  • University,非叶子结点,管理自己的子节点,聚合子节点
public class University extends OrganizationComponent{
    List<OrganizationComponent> colleges = new ArrayList<>();
    public University(String name, String des) {
        super(name, des);
    }
    @Override
    protected void add(OrganizationComponent oc) {
        colleges.add(oc);
    }
    @Override
    protected void remove(OrganizationComponent oc) {
        colleges.remove(oc);
    }
    @Override
    protected void show() {
        System.out.println(getName() + " - " + getDes());
        System.out.println("------------");
        for (OrganizationComponent college : colleges) {
            college.show();
            System.out.println("...........");
        }
    }
}
  • Department,叶子结点,不管理其他节点
public class Department extends OrganizationComponent{
    public Department(String name, String des) {
        super(name, des);
    }
    @Override
    protected void show() {
        System.out.println(getName() + " - " + getDes());
    }
}

HashMap源码

  • Map接口和AbstractMap,相当于组织抽象类 image.png
  • AbstractMap image.png
  • AbstractMap的put方法,有一个默认实现,意味着某个继承,不用put方法
public V put(K key, V value) {
    throw new UnsupportedOperationException();
}
  • HashMap,相当于学校,一个具体的组织,管理Node image.png
  • Node,相当于叶子结点,没有put方法 image.png
  • 类图 demo2.png

小结

  • 简化客户端操作,只需要面对一致的对象,不需要考虑整体部分,有较强的扩展性
  • 方便创建复杂的层次结构
  • 适用于,遍历组织结构,处理的对象组具有树形结构
  • 有较高的差异性,节点和叶子,没有很大的差异性,比较相似