装饰者模式 Decorator Pattern

一、模式介绍

1.1、定义

在不改变现有对象结构的情况下,动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。它是对象结构型模式。

1.2、优点

  1. 装饰者是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
  2. 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
  3. 装饰者模式完全遵守开闭原则

1.3、缺点

装饰者模式会增加许多子类,过度使用会增加程序的复杂度

二、结构与实现

2.1、结构

  • 装饰模式主要包含以下角色。
  1. 抽象组件(Compzonent)角色:定义一个抽象接口以规范准备接收附加责任的对象。
  2. 具体组件(ConcreteComponent)角色:实现抽象组件,可以动态地对具体组件加上新的行为。
  3. 抽象装饰(Decorator)角色:实现抽象组件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。这是装饰者共同实现的接口(也可以是抽象类)
  4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
    在这里插入图片描述

2.2、实现

设计一个咖啡订单系统,购买咖啡时,可以要求在其中加入各种调料,比如:摩卡(Mocha)、牛奶(Milk)。咖啡店会根据加入的调料不同收取不同的费用,所以订单系统必须考虑这些调料部分。类图如下:
在这里插入图片描述

2.2.1、Beverage
package com.erlang.decorator;

/**
 * @description: 抽象装饰者:饮料
 * @author: erlang
 * @since: 2022-02-13 22:39
 */
public abstract class Beverage {

    protected String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}
2.2.2、HouseBlend
package com.erlang.decorator;

/**
 * @description: 综合咖啡
 * @author: erlang
 * @since: 2022-02-13 22:39
 */
public class HouseBlend extends Beverage {

    public HouseBlend() {
        description = "House Blend Coffee";
    }

    @Override
    public double cost() {
        return .89;
    }
}
2.2.3、DarkRoast
package com.erlang.decorator;

/**
 * @description: 深焙咖啡
 * @author: erlang
 * @since: 2022-02-13 22:40
 */
public class DarkRoast  extends Beverage {

    public DarkRoast() {
        description = "DarkRoast coffee";
    }

    @Override
    public double cost() {
        return 0.99;
    }
}
2.2.4、CondimentDecorator
package com.erlang.decorator;

/**
 * @description: 具体装饰者:调料
 * @author: erlang
 * @since: 2022-02-13 22:39
 */
public abstract class CondimentDecorator extends Beverage {
    /**
     * 描述信息
     *
     * @return 描述信息
     */
    @Override
    public abstract String getDescription();
}
2.2.5、Milk
package com.erlang.decorator;

/**
 * @description: 牛奶
 * @author: erlang
 * @since: 2022-02-13 22:45
 */
public class Milk extends CondimentDecorator {

    private Beverage beverage;

    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }

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

    @Override
    public double cost() {
        return 0.99 + beverage.cost();
    }
}
2.2.6、Mocha
package com.erlang.decorator;

/**
 * @description: 摩卡
 * @author: erlang
 * @since: 2022-02-13 22:45
 */
public class Mocha extends CondimentDecorator {

    private Beverage beverage;

    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

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

    @Override
    public double cost() {
        return 0.20 + beverage.cost();
    }
}
2.2.7、StarBuzzCoffee
package com.erlang.decorator;

/**
 * @description: 咖啡店
 * @author: erlang
 * @since: 2022-02-13 22:48
 */
public class StarBuzzCoffee {
    public static void main(String[] args) {
        test1();
        test2();
        test3();
    }

    public static void test1() {
        Beverage houseBlend = new HouseBlend();
        System.out.println(houseBlend.getDescription() + " $" + houseBlend.cost());
        System.out.println("------------------------------------------");
    }

    public static void test2() {
        DarkRoast darkRoast = new DarkRoast();
        Mocha mocha = new Mocha(darkRoast);
        System.out.println(mocha.getDescription() + " $" + mocha.cost());
        System.out.println("------------------------------------------");
    }

    public static void test3() {
        HouseBlend houseBlend = new HouseBlend();
        Milk milk = new Milk(houseBlend);
        Mocha mocha = new Mocha(milk);
        System.out.println(mocha.getDescription() + " $" + mocha.cost());
        System.out.println("------------------------------------------");
    }
}
2.2.8、运行结果
House Blend Coffee $0.89
------------------------------------------
DarkRoast coffee, Mocha $1.19
------------------------------------------
House Blend Coffee, Milk, Mocha $2.08
------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值