Decorator概述
与其他模式区别
装饰器模式和代理模式看上去编程方式非常非常相似,它们有时候还可以称为包装模式,因此你会在一些代码中看到Wrapper这样的命名。代理模式中被包装的对象往往不希望或者不方便直接使用,依此代理类起到了隐藏被代理对象的访问,代理模式更在意对外层包装类的调用。在装饰器模式中,每个组件只提供部分功能,组件经常以一种链式嵌套的方式动态的组合在一起,装饰器模式并不在意是否要隐藏另一个被装饰的对象,而是在意多个组件合成后提供的整体功能。
玩具代码案例 - 咖啡调味
被装饰的类型
ICoffee
package online.javabook.gof.structural.patterns4.decorator.coffee.api;
public interface ICoffee {
String getCup();
}
DecoratorCoffee
package online.javabook.gof.structural.patterns4.decorator.coffee.api;
public class DecoratorCoffee implements ICoffee {
private ICoffee coffee;
public DecoratorCoffee(ICoffee coffee) {
this.coffee = coffee;
}
public DecoratorCoffee() {
}
@Override
public String getCup() {
if(coffee!=null) {
return coffee.getCup();
}
else{
return "";
}
}
}
装饰器角色
SimpleCoffee
package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
public class SimpleCoffee extends DecoratorCoffee {
public SimpleCoffee() {
super();
}
public SimpleCoffee(ICoffee coffee) {
super(coffee);
}
@Override
public String getCup() {
return super.getCup() + " + " + "Coffee";
}
}
IceCoffee
package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
public class IceCoffee extends DecoratorCoffee {
public IceCoffee() {
super();
}
public IceCoffee(ICoffee coffee) {
super(coffee);
}
@Override
public String getCup() {
return super.getCup() + " + " + "Ice";
}
}
MilkCoffee
package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
public class MilkCoffee extends DecoratorCoffee {
public MilkCoffee() {
super();
}
public MilkCoffee(ICoffee coffee) {
super(coffee);
}
@Override
public String getCup() {
return super.getCup() + " + " + "Milk";
}
}
SaltCoffee
package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
public class SaltCoffee extends DecoratorCoffee {
public SaltCoffee() {
super();
}
public SaltCoffee(ICoffee coffee) {
super(coffee);
}
@Override
public String getCup() {
return super.getCup() + " + " + "Salt";
}
}
SugarCoffee
package online.javabook.gof.structural.patterns4.decorator.coffee.impl;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.DecoratorCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
public class SugarCoffee extends DecoratorCoffee {
public SugarCoffee() {
super();
}
public SugarCoffee(ICoffee coffee) {
super(coffee);
}
@Override
public String getCup() {
return super.getCup() + " + " + "Sugar";
}
}
不基于装饰器模式的实现
代码逻辑相互叠加
Main
package org.gof.structural.patterns4.decorator.app.bad;
import online.javabook.gof.structural.patterns4.decorator.coffee.impl.MilkCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.impl.SaltCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.impl.SimpleCoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.impl.SugarCoffee;
public class Main {
public static void main(String[] args) {
String consumer = "consumer1";
if (consumer.equals("consumer1")) {
String coffee =
new SimpleCoffee().getCup() +
new SugarCoffee().getCup() +
new MilkCoffee().getCup() +
new SaltCoffee().getCup();
System.out.println(coffee);
} else if (consumer.equals("consumer2")) {
String coffee =
new SaltCoffee().getCup() +
new SaltCoffee().getCup() +
new SimpleCoffee().getCup() +
new SugarCoffee().getCup();
System.out.println(coffee);
} else if (consumer.equals("consumer3")) {
String coffee =
new SimpleCoffee().getCup() +
new SugarCoffee().getCup() +
new SugarCoffee().getCup() +
new SaltCoffee().getCup();
System.out.println(coffee);
}
}
}
Console
Simple + Sugar + Milk + Salt +
基于装饰器模式的实现
代码逻辑通过装饰器相互装饰
Main
package online.javabook.gof.structural.patterns4.decorator.app.good;
import online.javabook.gof.structural.patterns4.decorator.coffee.api.ICoffee;
import online.javabook.gof.structural.patterns4.decorator.coffee.impl.*;
public class Main {
public static void main(String[] args) {
String consumer = "consumer1";
if (consumer.equals("consumer1")) {
// coffee + sugar + milk + salt
ICoffee coffee = new SaltCoffee(new MilkCoffee( new SugarCoffee( new SimpleCoffee())));
System.out.println(coffee.getCup());
} else if (consumer.equals("consumer2")) {
// coffee + ice + salt + milk
ICoffee coffee = new MilkCoffee(new SaltCoffee( new IceCoffee( new SimpleCoffee())));
System.out.println(coffee.getCup());
} else if (consumer.equals("consumer3")) {
// coffee + sugar + sugar + milk
ICoffee coffee = new MilkCoffee(new SugarCoffee( new SugarCoffee( new SimpleCoffee())));
System.out.println(coffee.getCup());
}
}
}
Console
+ Coffee + Sugar + Milk + Salt