源代码
GitHub源代码
1.本文目标
本文目标是为了让大家认识并理解装饰器模式
2.基本套路
定义:在不改变原有对象的基础之上,将功能附加到对象上
类型:结构型
选择关键点:添加的功能是否需要动态组装
设计原则:遵循迪米特、单一职责、开闭原则,破坏里氏替换,体现功能复用
使用概率:99.99999%
难度系数:中
3.适用场景
1.扩展一个类的功能或给一个类添加附加职责
2.动态的给一个对象添加功能,这些功能可以再动态的撤销
4.使用步骤
用具体的栗子更容易说明问题,继续往下看
5.举个栗子
我们用具体的代码去更好的理解这个设计模式
5.1栗子说明
- 背景:公司的小伙伴小王饿了,想买个煎饼
- 目的:不仅仅是吃个煎饼,他还想加蛋,加烤肠,希望用装饰器模式实现
5.2使用步骤
实现代码如下:
步骤1.创建抽象的实体类(抽象的煎饼)
public abstract class ABatterCake {
public abstract String getDesc();
public abstract int cost();
}
步骤2.创建具体的实体类(具体的煎饼)继承抽象的实体类
public class BatterCake extends ABatterCake {
@Override
public String getDesc() {
return "煎饼";
}
@Override
public int cost() {
return 8;
}
}
步骤3.创建抽象的装饰类,继承抽象的实体类(抽象的煎饼)
public class AbstractDecorator extends ABatterCake{
private ABatterCake mBatterCake;//抽象的煎饼,当然也可以传具体的煎饼
public AbstractDecorator(ABatterCake mBatterCake) {
this.mBatterCake = mBatterCake;
}
@Override
public String getDesc() {
return this.mBatterCake.getDesc();
}
@Override
public int cost() {
return this.mBatterCake.cost();
}
}
步骤4. 创建具体的装饰类(鸡蛋装饰类),继承抽象的装饰类
public class EggDecorator extends AbstractDecorator {
public EggDecorator(ABatterCake mBatterCake) {
super(mBatterCake);
}
@Override
public String getDesc() {
return super.getDesc()+"加一个鸡蛋";
}
@Override
public int cost() {
return super.cost()+1;
}
}
步骤5. 创建具体的装饰类(烤肠装饰类),继承抽象的装饰类
public class SausageDecorator extends AbstractDecorator {
public SausageDecorator(ABatterCake mBatterCake) {
super(mBatterCake);
}
@Override
public String getDesc() {
return super.getDesc()+"加一个烤肠";
}
@Override
public int cost() {
return super.cost()+2;
}
}
步骤6. 测试
public static void main(String[] args) {
ABatterCake batterCake;
//煎饼
batterCake = new com.yadong.pattern.structural.decorator.v2.BatterCake();
//加蛋
batterCake = new EggDecorator(batterCake);
//在加蛋
batterCake = new EggDecorator(batterCake);
//加个烤肠
batterCake = new SausageDecorator(batterCake);
/**
* 输出结果:
* 8+1+1+2=12块钱
* 煎饼加一个鸡蛋加一个鸡蛋加一个烤肠 销售价格:12
*/
System.out.println(batterCake.getDesc()+" 销售价格:"+batterCake.cost());
/**
* 另外一种写法,连起来写
* 输出结果:
* 煎饼加一个鸡蛋加一个烤肠加一个烤肠 销售价格:13
* 煎饼+蛋+烤肠+烤肠
* 8+1+2+2=13块钱
*/
SausageDecorator sausageBatterCake= new SausageDecorator(new SausageDecorator(new EggDecorator(new BatterCake())));
System.out.println(sausageBatterCake.getDesc()+" 销售价格:"+sausageBatterCake.cost());
}
6.优点
- 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
- 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
- 符合开闭原则
7.缺点
- 会出现更多的代码,更多的类,增加程序复杂性
- 动态装饰时,多层装饰会更复杂
8.总结
本文只是对装饰模式进行一个分享,接下来会从创建型模式,结构型模式,行为型模式,这三大类展开一个系列分享,大家可以持续进行关注,信仰年輕的设计模式,蟹蟹啦。
网友评论