【设计模式达摩院】03 装饰者模式本质内涵b

场景

动态为一个类增加新功能

用于替代继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

概念

  1. 利用组合(Composition)和委托可以在运行时具有继承行为的效果

  2. 利用子类继承是在编译时静态决定的,所有子类具有相同行为,然而如果利用组合的做法扩展对象行为,就可以在运动时动态扩展。

  3. 开闭原则,允许在不修改代码的情况下就可以搭配新的行为。引入开闭原则会引入新的抽象层次和复杂度。

组件

装饰者模式的基本说明

  • component 抽象组件,与真实对象有相同的接口,这样客户可以通过操作抽象组件无差别操作真实对象。

  • ConcreateComponent真实对象

  • Decorator装饰器,持有抽象组件的引用,可以用来调用新增的装饰功能

  • ConcreateDecorator具体的装饰角色,每个角色代表一个新增的功能

概念

装饰者模式动态的将责任行为添加到目标对象上,若要扩展功能只需要用装饰者包装目标实例。

  1. 装饰者和被装饰着是通过extends实现的。这里继承主要是为了和父类保持相同类型,而非获取其属性和行为。装饰者为对象添加新的行为是通过组合而非继承实现的。通过多个装饰者层层装饰记即可达到添加任意行为组合的目的。
  2. 缺点:装饰者模式会产生大量小类,数量太多对使用者带来困扰。例如IO流的类比较多,对于接触着来说需要一定时间理解。

示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SaE7wnOm-1618117995167)【设计模式达摩院】03 装饰者模式本质内涵b

package com.kouryoushine.deginmodel.decorator.coffee;

/**
 * @ClassName Beverage
 * @Description TODO
 * @Author kouryoushine
 * @Date 2021/4/11 11:10
 * @Version 1.0
 */
public abstract class Beverage {
    public   String description="unknown beverage";

    public String   getDescription(){
     return   description;
    }

    /**
     * 计算咖啡价格
     * @return
     */
    public abstract double cost();
}

package com.kouryoushine.deginmodel.decorator.coffee;

/**
 * @ClassName CondimentDecorator
 * @Description TODO
 * @Author kouryoushine
 * @Date 2021/4/11 11:17
 * @Version 1.0
 */
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

package com.kouryoushine.deginmodel.decorator.coffee.product;

import com.kouryoushine.deginmodel.decorator.coffee.Beverage;

/**
 * @ClassName Espresso
 * @Description TODO
 * @Author kouryoushine
 * @Date 2021/4/11 11:28
 * @Version 1.0
 */
public class Espresso extends Beverage {

    //设置饮料属性
    public Espresso() {
        description="Espresso";
    }

    /**
     * 返回饮料自身价格
     * @return
     */
    @Override
    public double cost() {
        return 1.99;
    }
}

package com.kouryoushine.deginmodel.decorator.coffee.condiment;

import com.kouryoushine.deginmodel.decorator.coffee.Beverage;
import com.kouryoushine.deginmodel.decorator.coffee.CondimentDecorator;

/**
 * @ClassName Milk
 * @Description TODO
 * @Author kouryoushine
 * @Date 2021/4/11 11:20
 * @Version 1.0
 */
public class Milk extends CondimentDecorator {
    // 饮料
    Beverage beverage;

    //构造器用于装饰上级
    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription()+",Milk";
    }

    @Override
    public double cost() {
        return .10+beverage.cost();
    }
}

总结

个人感觉装饰者模式在一spring框架为背景的模式下并无太大用处。虽然能带来一定动态扩展的能力,但同时带来了类太多的问题。java的IO流用起来过于繁琐,面向过程的开发模式必然被抛弃,面向声明式的开发才是主流。仅作为开发模式,用到的时候能想到即可。

上一篇:Java中的装饰器模式(Decorator)


下一篇:UML第二部分和创建型模式2.0