装饰模式又叫做包装模式,其功能是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活,是继承关系的一个替换方案。

    【使用场景】

    • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
    • 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实,使得子类数目呈爆炸性增长。
    • 当不能采用生成子类的方法进行扩充时。

    【角色】

    • 抽象构件(Component):Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象(在装饰模式中,必然有一个最基本、最核心、最原始的接口或抽象类充当Component抽象构件)。
    • 具体构件(ConcreteComponent):ConcreteComponent 具体构件,是Component的具体实现,要装饰的就是它。
    • 装饰角色(Decorator):一般是一个抽象类,实现Component接口或者抽象方法,它里面可不一定有抽象的方法呀,它的属性里必然有一个private变量指向Component抽象构件(如果具体装饰角色只有一个,这个可以省略)。
    • 具体装饰角色(ConcreteDecorator):把你最核心的、最原始的、最基本的东西装饰成想要的东西。

      1. /**
      2. * 饮料(抽象构件)
      3. */
      4. public interface Beverage {
      5. /**
      6. * 描述
      7. */
      8. String desc();
      9. /**
      10. * 价格
      11. */
      12. Integer cost();
      13. }
      1. /**
      2. * 绿茶(具体构件)
      3. */
      4. public class GreenTea implements Beverage {
      5. @Override
      6. public String desc() {
      7. return "绿茶(" + cost() + "元)";
      8. }
      9. @Override
      10. public Integer cost() {
      11. return 12;
      12. }
      13. }
      1. /**
      2. * 红茶(具体构件)
      3. */
      4. public class RedTea implements Beverage {
      5. @Override
      6. public String desc() {
      7. return "红茶(" + cost() + "元)";
      8. }
      9. @Override
      10. public Integer cost() {
      11. return 10;
      12. }
      13. }
      1. /**
      2. * 调料抽象类(装饰角色)
      3. */
      4. public abstract class Condiment implements Beverage {
      5. private Beverage beverage;
      6. public Condiment(Beverage beverage) {
      7. this.beverage = beverage;
      8. }
      9. /**
      10. * 描述
      11. */
      12. @Override
      13. public String desc() {
      14. return this.beverage.desc();
      15. }
      16. /**
      17. * 价格
      18. */
      19. @Override
      20. public Integer cost() {
      21. return this.beverage.cost();
      22. }
      23. }
      1. /**
      2. * 柠檬(具体装饰角色)
      3. */
      4. public class Lemon extends Condiment {
      5. public Lemon(Beverage beverage) {
      6. super(beverage);
      7. }
      8. /**
      9. * 描述
      10. */
      11. @Override
      12. public String desc() {
      13. return super.desc() + " + 柠檬(2元)";
      14. }
      15. /**
      16. * 价格
      17. */
      18. @Override
      19. public Integer cost() {
      20. return super.cost() + 2;
      21. }
      22. }
      1. /**
      2. * 芒果(具体装饰角色)
      3. */
      4. public class Mango extends Condiment {
      5. public Mango(Beverage beverage) {
      6. super(beverage);
      7. }
      8. /**
      9. * 描述
      10. */
      11. @Override
      12. public String desc() {
      13. return super.desc() + " + 芒果(3元)";
      14. }
      15. /**
      16. * 价格
      17. */
      18. @Override
      19. public Integer cost() {
      20. return super.cost() + 3;
      21. }
      22. }
      1. public class DecoratorTest {
      2. public static void main(String[] args) {
      3. Beverage greenTea = new Lemon(new Mango(new GreenTea()));
      4. System.out.println(greenTea.desc() + " = 售价:" + greenTea.cost());
      5. Beverage redTea = new Mango(new Mango(new RedTea()));
      6. System.out.println(redTea.desc() + " = 售价:" + redTea.cost());
      7. }
      8. }
      9. ----输出----
      10. 绿茶(12元) + 芒果(3元) + 柠檬(2元) = 售价:17
      11. 红茶(10元) + 芒果(3元) + 芒果(3元) = 售价:16