全文: 959 字, 预计阅读时间: 8 分钟
定义:
装饰模式 (Decorator) 动态地给一个对象添加一些额外的职责. 就增加功能来说, 装饰模式比生成子类更加灵活.
这里可以举一个生活中的例子, 一个蛋糕, 在蛋糕上摆上水果, 这个蛋糕就变成了水果蛋糕, 给这个水果蛋糕插上蜡烛, 它就变成了一个生日蛋糕.(这是 Head First 中的一个例子, 个人觉得非常的形象, 记忆犹新).
分析:
如果我们需要扩展一个类的功能, 你会怎么做呢? 如果直接修改这个类, 我们就违反了开闭原则(对修改关闭, 对扩展开放).
我们可以继承这个类, 写一个这个类的子类, 用于实现扩展功能, 也可以使用组合(将这个类作为成员变量), 达到相同的效果.
我们将继承这种关系称为 is-a, 组合这种关系称为 use-a.is-a 的耦合程度要高于 use-a, 所以我们经常可以听到这样的说法: 组合优于继承, 原因就是这两种关系的耦合程度不同.
装饰模式的核心思想, 其实就是用组合代替继承.
图解:
实例:
这里举一个咖啡店的例子, 咖啡的原料是咖啡豆, 我们可以使用咖啡豆和牛奶, 蜂蜜, 摩卡组合出不同价格, 不同口味的咖啡.
这里咖啡豆就是被装饰的对象, 也就是图示中的 ConcreteComponent, 饮品类就是我们抽象出的 Component, 定义了展示价格和材料两个方法. 牛奶, 蜂蜜, 摩卡是装饰对象, 也就是图中的 ConcreteDecoratorA,ConcreteDecoratorB. 他们抽象出的 Decorator, 同样定义了展示价格和材料两个方法, 具体类图与实现如下:
代码:
- /**
- * 饮品.
- *
- * @author jialin.li
- * @date 2019-12-26 22:58
- */
- public interface Beverage {
- /** 获取描述 */
- String getDescription();
- /** 获取金额 */
- double getPrice();
- }
- /**
- * 咖啡豆 1
- *
- * @author jialin.li
- * @date 2019-12-26 22:59
- */
- public class CoffeeBean1 implements Beverage {
- @Override
- public String getDescription() {
- return "第一种咖啡豆";
- }
- @Override
- public double getPrice() {
- return 10d;
- }
- }
- /**
- * 咖啡豆 2
- *
- * @author jialin.li
- * @date 2019-12-26 23:00
- */
- public class CoffeeBean2 implements Beverage{
- @Override
- public String getDescription() {
- return "第一种咖啡豆";
- }
- @Override
- public double getPrice() {
- return 12.5d;
- }
- }
- /**
- * 装饰器.
- *
- * @author jialin.li
- * @date 2019-12-26 23:02
- */
- public class Decorator implements Beverage{
- protected Beverage coffee;
- @Override
- public String getDescription() {
- return "装饰器, 由子类重写方法";
- }
- @Override
- public double getPrice() {
- return 0;
- }
- }
- /**
- * 蜂蜜.
- *
- * @author jialin.li
- * @date 2019-12-26 23:07
- */
- public class Honey extends Decorator {
- public Honey(Beverage coffee) {
- this.coffee = coffee;
- }
- @Override
- public String getDescription() {
- return coffee.getDescription() + "加蜂蜜";
- }
- @Override
- public double getPrice() {
- return coffee.getPrice() + 4.5d;
- }
- }
- /**
- * 牛奶.
- *
- * @author jialin.li
- * @date 2019-12-26 23:03
- */
- public class Milk extends Decorator {
- public Milk(Beverage coffee) {
- this.coffee = coffee;
- }
- @Override
- public String getDescription() {
- return coffee.getDescription() + "加牛奶";
- }
- @Override
- public double getPrice() {
- return coffee.getPrice() + 1.5d;
- }
- }
- /**
- * 摩卡.
- *
- * @author jialin.li
- * @date 2019-12-26 23:05
- */
- public class Mocha extends Decorator {
- public Mocha(Beverage coffee) {
- this.coffee = coffee;
- }
- @Override
- public String getDescription() {
- return coffee.getDescription() + "加摩卡";
- }
- @Override
- public double getPrice() {
- return coffee.getPrice() + 2.5d;
- }
- }
- /**
- * 测试类.
- *
- * @author jialin.li
- * @date 2019-12-26 23:09
- */
- public class Main {
- public static void main(String[] args) {
- CoffeeBean1 coffee1 = new CoffeeBean1();
- CoffeeBean2 coffee2 = new CoffeeBean2();
- // 加蜂蜜
- Beverage honey = new Honey(coffee1);
- // 加摩卡
- Beverage mocha = new Mocha(honey);
- System.out.println(mocha.getDescription());
- System.out.println(mocha.getPrice());
- // 加牛奶
- Milk milk = new Milk(coffee2);
- System.out.println(milk.getDescription());
- System.out.println(milk.getPrice());
- }
- }
结果:
第一种咖啡豆加蜂蜜加摩卡
17.0
第一种咖啡豆加牛奶
14.0
来源: http://www.bubuko.com/infodetail-3351974.html