装饰者模式是允许向一个新对象添加新的功能,但又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
就增加功能来说,装饰器模式相比生成子类更为灵活。
例子:
如果我们去咖啡店,有一种咖啡,该咖啡可以加糖,牛奶,奶泡等等,如果我们需要加糖和牛奶,常规的写法就是分别继承糖的接口和牛奶的接口,然后实现。但是如果添加种类很多的话,就会形成大量的继承类,给维护造成很大的麻烦。这就需要继承类来为其添加新功能了。
Coffee接口
public abstract class Coffee {
public abstract int getPrice();
public abstract String getName();
}
原始咖啡
public class SimpleCoffee extends Coffee {
@Override
public int getPrice() {
return 10;
}
@Override
public String getName() {
return "原始咖啡";
}
}
Decorator类
public abstract class Decorator extends Coffee {
//用于传递Coffee对象
public Coffee coffee;
public Decorator(Coffee coffee){
this.coffee = coffee;
}
}
MilkDecorator类
public class MilkDecorator extends Decorator {
public MilkDecorator(Coffee coffee){
super(coffee);
}
@Override
public int getPrice() {
return coffee.getPrice()+10;
}
@Override
public String getName() {
return coffee.getName() + "milk";
}
测试
public class Test {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getPrice());
}
}
如果你想加糖可以
coffee = new SugarDecorator(coffee);
等等
这样我们就可以方便的为咖啡提供各种配料了。
装饰者模式和代理模式的区别
两者都可以在不改变原始类的结构的前提下,为新对象提供新功能。但是两者也是有区别的:
在用法上:用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。
运行时:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,并不支持多层嵌套,而装饰者能够在运行时递归地被构造。
详细的可以看这个链接: https://www.cnblogs.com/jaredlam/archive/2011/11/08/2241089.html