Decorator概述

Decorator - 图1

与其他模式区别

装饰器模式和代理模式看上去编程方式非常非常相似,它们有时候还可以称为包装模式,因此你会在一些代码中看到Wrapper这样的命名。代理模式中被包装的对象往往不希望或者不方便直接使用,依此代理类起到了隐藏被代理对象的访问,代理模式更在意对外层包装类的调用。在装饰器模式中,每个组件只提供部分功能,组件经常以一种链式嵌套的方式动态的组合在一起,装饰器模式并不在意是否要隐藏另一个被装饰的对象,而是在意多个组件合成后提供的整体功能。

玩具代码案例 - 咖啡调味

被装饰的类型

ICoffee

  1. package online.javabook.gof.structural.patterns4.decorator.coffee.api;
  2. public interface ICoffee {
  3. String getCup();
  4. }

DecoratorCoffee

  1. package online.javabook.gof.structural.patterns4.decorator.coffee.api;
  2. public class DecoratorCoffee implements ICoffee {
  3. private ICoffee coffee;
  4. public DecoratorCoffee(ICoffee coffee) {
  5. this.coffee = coffee;
  6. }
  7. public DecoratorCoffee() {
  8. }
  9. @Override
  10. public String getCup() {
  11. if(coffee!=null) {
  12. return coffee.getCup();
  13. }
  14. else{
  15. return "";
  16. }
  17. }
  18. }

装饰器角色

SimpleCoffee

  1. package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
  2. import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
  3. import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
  4. public class SimpleCoffee extends DecoratorCoffee {
  5. public SimpleCoffee() {
  6. super();
  7. }
  8. public SimpleCoffee(ICoffee coffee) {
  9. super(coffee);
  10. }
  11. @Override
  12. public String getCup() {
  13. return super.getCup() + " + " + "Coffee";
  14. }
  15. }

IceCoffee

  1. package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
  2. import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
  3. import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
  4. public class IceCoffee extends DecoratorCoffee {
  5. public IceCoffee() {
  6. super();
  7. }
  8. public IceCoffee(ICoffee coffee) {
  9. super(coffee);
  10. }
  11. @Override
  12. public String getCup() {
  13. return super.getCup() + " + " + "Ice";
  14. }
  15. }

MilkCoffee

  1. package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
  2. import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
  3. import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
  4. public class MilkCoffee extends DecoratorCoffee {
  5. public MilkCoffee() {
  6. super();
  7. }
  8. public MilkCoffee(ICoffee coffee) {
  9. super(coffee);
  10. }
  11. @Override
  12. public String getCup() {
  13. return super.getCup() + " + " + "Milk";
  14. }
  15. }

SaltCoffee

  1. package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
  2. import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
  3. import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
  4. public class SaltCoffee extends DecoratorCoffee {
  5. public SaltCoffee() {
  6. super();
  7. }
  8. public SaltCoffee(ICoffee coffee) {
  9. super(coffee);
  10. }
  11. @Override
  12. public String getCup() {
  13. return super.getCup() + " + " + "Salt";
  14. }
  15. }

SugarCoffee

  1. package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
  2. import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
  3. import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
  4. public class SugarCoffee extends DecoratorCoffee {
  5. public SugarCoffee() {
  6. super();
  7. }
  8. public SugarCoffee(ICoffee coffee) {
  9. super(coffee);
  10. }
  11. @Override
  12. public String getCup() {
  13. return super.getCup() + " + " + "Sugar";
  14. }
  15. }

不基于装饰器模式的实现

代码逻辑相互叠加

Main

  1. package org.gof.structural.patterns4.decorator.app.bad;
  2. import online.javabook.gof.structural.patterns4.decorator.coffee.impl.MilkCoffee;
  3. import online.javabook.gof.structural.patterns4.decorator.coffee.impl.SaltCoffee;
  4. import online.javabook.gof.structural.patterns4.decorator.coffee.impl.SimpleCoffee;
  5. import online.javabook.gof.structural.patterns4.decorator.coffee.impl.SugarCoffee;
  6. public class Main {
  7. public static void main(String[] args) {
  8. String consumer = "consumer1";
  9. if (consumer.equals("consumer1")) {
  10. String coffee =
  11. new SimpleCoffee().getCup() +
  12. new SugarCoffee().getCup() +
  13. new MilkCoffee().getCup() +
  14. new SaltCoffee().getCup();
  15. System.out.println(coffee);
  16. } else if (consumer.equals("consumer2")) {
  17. String coffee =
  18. new SaltCoffee().getCup() +
  19. new SaltCoffee().getCup() +
  20. new SimpleCoffee().getCup() +
  21. new SugarCoffee().getCup();
  22. System.out.println(coffee);
  23. } else if (consumer.equals("consumer3")) {
  24. String coffee =
  25. new SimpleCoffee().getCup() +
  26. new SugarCoffee().getCup() +
  27. new SugarCoffee().getCup() +
  28. new SaltCoffee().getCup();
  29. System.out.println(coffee);
  30. }
  31. }
  32. }

Console

  1. Simple + Sugar + Milk + Salt +

基于装饰器模式的实现

代码逻辑通过装饰器相互装饰

Main

  1. package online.javabook.gof.structural.patterns4.decorator.app.good;
  2. import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
  3. import online.javabook.gof.structural.patterns4.decorator.coffee.impl.*;
  4. public class Main {
  5. public static void main(String[] args) {
  6. String consumer = "consumer1";
  7. if (consumer.equals("consumer1")) {
  8. // coffee + sugar + milk + salt
  9. ICoffee coffee = new SaltCoffee(new MilkCoffee( new SugarCoffee( new SimpleCoffee())));
  10. System.out.println(coffee.getCup());
  11. } else if (consumer.equals("consumer2")) {
  12. // coffee + ice + salt + milk
  13. ICoffee coffee = new MilkCoffee(new SaltCoffee( new IceCoffee( new SimpleCoffee())));
  14. System.out.println(coffee.getCup());
  15. } else if (consumer.equals("consumer3")) {
  16. // coffee + sugar + sugar + milk
  17. ICoffee coffee = new MilkCoffee(new SugarCoffee( new SugarCoffee( new SimpleCoffee())));
  18. System.out.println(coffee.getCup());
  19. }
  20. }
  21. }

Console

 + Coffee + Sugar + Milk + Salt