装饰模式又叫做包装模式,其功能是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活,是继承关系的一个替换方案。
【使用场景】
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实,使得子类数目呈爆炸性增长。
- 当不能采用生成子类的方法进行扩充时。
【角色】
- 抽象构件(Component):Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象(在装饰模式中,必然有一个最基本、最核心、最原始的接口或抽象类充当Component抽象构件)。
- 具体构件(ConcreteComponent):ConcreteComponent 具体构件,是Component的具体实现,要装饰的就是它。
- 装饰角色(Decorator):一般是一个抽象类,实现Component接口或者抽象方法,它里面可不一定有抽象的方法呀,它的属性里必然有一个private变量指向Component抽象构件(如果具体装饰角色只有一个,这个可以省略)。
具体装饰角色(ConcreteDecorator):把你最核心的、最原始的、最基本的东西装饰成想要的东西。
/*** 饮料(抽象构件)*/public interface Beverage {/*** 描述*/String desc();/*** 价格*/Integer cost();}
/*** 绿茶(具体构件)*/public class GreenTea implements Beverage {@Overridepublic String desc() {return "绿茶(" + cost() + "元)";}@Overridepublic Integer cost() {return 12;}}
/*** 红茶(具体构件)*/public class RedTea implements Beverage {@Overridepublic String desc() {return "红茶(" + cost() + "元)";}@Overridepublic Integer cost() {return 10;}}
/*** 调料抽象类(装饰角色)*/public abstract class Condiment implements Beverage {private Beverage beverage;public Condiment(Beverage beverage) {this.beverage = beverage;}/*** 描述*/@Overridepublic String desc() {return this.beverage.desc();}/*** 价格*/@Overridepublic Integer cost() {return this.beverage.cost();}}
/*** 柠檬(具体装饰角色)*/public class Lemon extends Condiment {public Lemon(Beverage beverage) {super(beverage);}/*** 描述*/@Overridepublic String desc() {return super.desc() + " + 柠檬(2元)";}/*** 价格*/@Overridepublic Integer cost() {return super.cost() + 2;}}
/*** 芒果(具体装饰角色)*/public class Mango extends Condiment {public Mango(Beverage beverage) {super(beverage);}/*** 描述*/@Overridepublic String desc() {return super.desc() + " + 芒果(3元)";}/*** 价格*/@Overridepublic Integer cost() {return super.cost() + 3;}}
public class DecoratorTest {public static void main(String[] args) {Beverage greenTea = new Lemon(new Mango(new GreenTea()));System.out.println(greenTea.desc() + " = 售价:" + greenTea.cost());Beverage redTea = new Mango(new Mango(new RedTea()));System.out.println(redTea.desc() + " = 售价:" + redTea.cost());}}----输出----绿茶(12元) + 芒果(3元) + 柠檬(2元) = 售价:17红茶(10元) + 芒果(3元) + 芒果(3元) = 售价:16
