概念
装饰器模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案.
下面以购物消费为例子
首先,我们创建一个消费者接口,并实现这个接口的人叫“渣渣辉”(被装饰者)。
public interface Person {
/**
* 总消费
*/
public Double cost();
public void show();
}
public class ZhangJiaHui implements Person {
@Override
public Double cost() {
// 默认消费为0
return 0.0;
}
@Override
public void show() {
System.out.println("大家好,我是渣渣辉!");
}
}
然后,创建一个装饰器的超类和被装饰者共同实现Person这个接口。
public abstract class ClothesDecorator implements Person {
// 装饰器中要使用的装饰器对象,构造方法传入
protected Person person;
public ClothesDecorator(Person person) {
this.person = person;
}
}
再创建子类去具体的实现这个超类(装饰器)的装饰内容,这里我们创建一个衣服和帽子的子类。
public class WearHat extends ClothesDecorator {
public WearHat(Person person) {
super(person);
}
@Override
public Double cost() {
// 加上帽子价钱
return person.cost() + 50;
}
@Override
public void show() {
person.show();
System.out.println("戴上了帽子,累计消费:" + this.cost());
}
}
public class WearJacket extends ClothesDecorator {
public WearJacket(Person person) {
super(person);
}
@Override
public Double cost() {
// 加上夹克价钱
return person.cost() + 100;
}
@Override
public void show() {
person.show();
System.out.println("穿上了夹克,累计消费:" + this.cost());
}
}
最后,对渣渣辉进行装饰并消费。
public static void main(String[] args) {
//创建一个渣渣辉
Person zhangjiahui = new ZhangJiaHui();
//穿上夹克
zhangjiahui = new WearJacket(zhangjiahui);
//戴上帽子
zhangjiahui = new WearHat(zhangjiahui);
zhangjiahui.show();
}
关键点
- 装饰器和被装饰类要实现同一个接口,或者继承统一各类。
- 装饰器中的方法可以调用被装饰对象提供的方法,以此实现功能累加的效果。
优点和缺点
优点:
- 扩展功能的方式比较灵活;
- 每一个装饰器相互独立,需要修改时不会互相影响;
- 符合开闭原则;
- 扩展功能不需要修改对象本身;
缺点:
- 多层装饰比较复杂,对于初学者不友好。