设计模式-装饰器模式
装饰器模式可以动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰器和被装饰的对象有两个特点:
1)他们实现同一个接口
2)装饰器中使用了被装饰的对象
1.假设老王来到商店里进行购物,老王可以这样做:
public class LaoWang { public void show(){ System.out.println("我穿上衣服,累计花费100元"); System.out.println("我穿上裤子,累计花费250元"); System.out.println("我穿上帽子,花费300元"); } }
每买一样东西,老王都得对show方法进行修改,违背了我们开发的开闭原则,所以老王可以使用装饰器模式动态的将需要做的事情添加到对象上。
2.构建装饰器超类,为装饰器提供被装饰的对象
/** * 装饰器超类,和被装饰的对象实现同一个接口 Person * 作用就是为装饰器类提供被装饰的对象 * @author yuans * @create 2018-10-30-21:02 */ public class ClothesDecorator implements Person { //装饰器中要使用被装饰器的对象,构造方法中传入 protected Person person; public ClothesDecorator(Person person) { this.person = person; } @Override public Double cost() { return null; } @Override public void show() { } }
3.老王穿上jacket
/**
* 具体的装饰,夹克
*
* @author yuans
* @create 2018-10-30-21:04
*/
public class Jacket extends ClothesDecorator {
public Jacket(Person person) {
super(person);
}
@Override
public void show() {
person.show();
System.out.println("穿上夹克,累计消费" + this.cost());
}
@Override
public Double cost() {
return person.cost() + 100; //夹克100元
}
}
4.老王穿上帽子
/** * 具体的装饰,帽子 * * @author yuans * @create 2018-10-30-21:06 */ public class Hat extends ClothesDecorator { public Hat(Person person) { super(person); } @Override public void show() { //执行已有功能 person.show(); //此处是附加的功能 System.out.println("戴上帽子,累计消费" + this.cost()); } @Override public Double cost() { return person.cost() + 50; //帽子50元 } }
5.测试类
/** * 装饰器模式测试类 * 1.装饰器和被装饰类要实现同一个接口(实际开发中也可能用继承) * 2.装饰器中使用了被装饰的对象。 * @author yuans * @create 2018-10-30-21:09 */ public class DecorateMain { public static void main(String[] args) { // Person laoWang = new Jacket(new LaoWang()); Person laoWang = new LaoWang(); laoWang = new Jacket(laoWang); laoWang = new Hat(laoWang); laoWang.show(); System.out.println("买单,老王总共消费:" + laoWang.cost()); } }
6.测试结果及总结
装饰器模式的作用是动态给对象增加一些功能,而不需要修改对象本身;扩展功能的方式比较灵活;每一个装饰器相互独立,需要修改时不会互相影响。