[2] [单一职责] ( 1 ) 装饰模式 Decorator (扩展主类功能时使用)

总结

  • what 有什么用?
    解决主类在多个方向的扩展功能的问题


  • when 什么场景用?
    扩展功能时用 (添加新功能/可选功能)


  • how 如何做?
    在运行时动态扩展对象的功能,
    而非在编译时静态的扩展.


  • 李建忠老师的一些讲解
    .
    通过采用组合而非继承的手法,
    Decorator模式实现了,
    运行时动态扩展对象功能的能力,
    而且可以根据需要扩展多个功能.
    避免了使用继承带来的"灵活性差"和"多子类衍生问题".
    .
    你如果在代码中, 看到一个类,
    他的父类是steam, 它里面又有一个字段是steam*,
    那么90%开发者使用了装饰模式.
    (即同时去继承以及组合同一个类)


  • 比较正式的说法
    动态(组合)地给一个对象增加一些额外的职责。就增加功
    能而言,Decorator模式比生成子类(继承)更为灵活(消
    除重复代码 & 减少子类个数)。


  • 关键词
    扩展功能
    .
    多方向
    .
    运行时扩展




C++例子

重构前

image


image




重构后

image

image




进一步重构

image




角色结构

image




JAVA例子

参考:
https://youtu.be/d-j0Zs0ngb8?si=SvHvLjzvcqk0EbB0

重构前

package v18_decorator.java;

interface Coffee {
    double cost();
}

class SimpleCoffee implements Coffee {
    public double cost() {
        return 2;
    }
}

class CoffeeWithMilk implements Coffee {
    public double cost() {
        return 2 + 0.5;
    }
}

class CoffeeWithSugar implements Coffee {
    public double cost() {
        return 2 + 0.25;
    }
}

class CoffeeWithMilkAndSugar implements Coffee {
    public double cost() {
        return 2 + 0.5 + 0.25;
    }
}

重构后

package v18_decorator.java;
 

interface Coffee {
    double cost();
}

// 基础咖啡
class SimpleCoffee implements Coffee {
    public double cost() {
        return 2;
    }
}

// 咖啡装饰器
abstract class CoffeeDecorator implements Coffee { // 这个继承为了符合标准,即cost()接口
    protected Coffee coffee; // 关键在这里

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public double cost() {
        return coffee.cost();
    }
}

// 牛奶
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    public double cost() {
        return coffee.cost() + 0.5;
    }
}

// 糖
class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    public double cost() {
        return coffee.cost() + 0.25;
    }
}

// 程序入口
public class Coffee2 {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        Coffee coffeeWithMilk = new MilkDecorator(coffee);
        Coffee coffeeWithMilkAndSugar = new SugarDecorator(coffeeWithMilk);

        System.out.println("Coffee cost: " + coffee.cost());
        System.out.println("Coffee with Milk cost: " + coffeeWithMilk.cost());
        System.out.println("Coffee with Milk and Sugar cost: " + coffeeWithMilkAndSugar.cost());
    }
}



image


角色结构

image




posted @ 2023-10-15 21:00  qwertzxc  阅读(8)  评论(0)    收藏  举报