装饰模式定义:
装饰模式就是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
装饰模式实现:
需求:净水器公司想要搞一波营销活动,买送净水机送三种礼品:鸡蛋,雨伞,洗菜盆,但是销售比较鸡贼这三种礼品不是必须都送的,会根据消费者的购买意愿来由销售来送几种礼品。
设计思路:实现抽象的Gift类是原始对象,有giveGift方法;SaleGift类是最核心的类,必须会执行也是需要装饰的类;Decorator类是装饰的抽象类,GiftDecorator1和GiftDecorator2是具体的装饰类。
类图:
代码实现:
/**
* 装饰模式
* 礼品抽象类
*/
public abstract class Gift {
protected abstract void giveGift();
}
/**
* 销售礼品
*/
public class SaleGift extends Gift {
@Override
protected void giveGift() {
System.out.println("只要下单就送鸡蛋");
}
}
/**
* 装饰器模式
*装饰抽象类
*/
public abstract class Decorator extends Gift{
private Gift gift;
//需要装饰的类
public Decorator(Gift gift){
this.gift = gift;
}
@Override
protected void giveGift() {
this.gift.giveGift();
}
}
/**
* 装饰器模式
* 装饰类1
*/
public class GiftDecorator1 extends Decorator{
//被修饰的对象
public GiftDecorator1(Gift gift) {
super(gift);
}
//自己的装饰方法
private void giveSalfGift(){
System.out.println("再送一把天堂伞");
}
//重写父类方法
protected void giveGift() {
super.giveGift();
giveSalfGift();
}
}
/**
* 装饰器模式
* 装饰类2
*/
public class GiftDecorator2 extends Decorator{
//被修饰的对象
public GiftDecorator2(Gift gift) {
super(gift);
}
//自己的装饰方法
private void giveSalfGift(){
System.out.println("再送一套不锈钢盆");
}
//重写父类方法
protected void giveGift() {
super.giveGift();
giveSalfGift();
}
}
/**
* 装饰器模式
* 测试场景
*/
public class TestDecorator {
public static void main(String[] args) {
System.out.println("开始销售净水机========");
Gift gift = new SaleGift();
gift.giveGift();
System.out.println("购买意愿的不够强烈=========");
//第一次修饰
gift = new GiftDecorator1(gift);
gift.giveGift();
System.out.println("开始犹豫==========");
// 第二次修饰
gift = new GiftDecorator2(gift);
gift.giveGift();
System.out.println("最终销售成功===========");
}
}
//执行结果
开始销售净水机========
只要下单就送鸡蛋
购买意愿的不够强烈=========
只要下单就送鸡蛋
再送一把天堂伞
开始犹豫==========
只要下单就送鸡蛋
再送一把天堂伞
再送一套不锈钢盆
最终销售成功===========
SaleGift类最终被装饰了两次,每次装饰都是在原有的核心功能上加上了装饰类特有的处理方法。而装饰模式最根本的原理每次进行装饰时传入的构造方法的调用父类的构造方法进行初始化。而无论的装饰类还是核心类都继承Gift的子类。所以装饰模式其实时利用继承的特性,而又丰富了继承的一种手段。
总结:
装饰模式是为了解决继承关系过于复杂的场景,通过组合来代替继承,增强原有类的功能,装饰模式还可以通过多个装饰器来装饰,不过装饰器类需要继承和被装饰类的相同的类或者接口。
- 装饰模式的优点:首先装饰类和被装饰类是可以独立发展的,没有耦合关系。装饰模式是继承关系的一种替代产品,因为装 饰类最终继承的也原始类。而被装饰类也是如此。但是装饰模式的比继承可扩展性要高,而且更灵活。
- 装饰模式的缺点:装饰模式的装饰层数不宜过多,过多的装饰效果会是代码像剥洋葱一样,同时代码不容维护和调试。
- 适用场景: 当需求变更时,在原有功能上增加附属功能时,在保证原有功能的基础上,不妨试试装饰模式。
参考《设计模式之禅》秦小波著