常用设计模式——装饰模式
常用设计模式——装饰模式
定义:动态给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活
案例分析:
大家都是上班族,同为苦逼的程序员,工作节奏一般都是996,很辛苦,所以呢,想必大家都和我一样,休息时间很少,睡眠时间更少,早上是不会做饭的,一般在公司楼下买个早餐之类的,到公司就边吃东西边撸代码了。
早上一般都是吃个煎饼啥的,比如山东杂粮煎饼,这里为它打个广告,确实好吃(手抓饼也是一样的哦)。
为什么绕这么大个圈子说早餐呢,还是煎饼早餐,目的就是为了引入装饰模式,想必大家都知道煎饼有很多种类,
比如:
- 煎饼+鸡蛋
- 煎饼+鸡蛋+火腿
- 煎饼+鸡蛋+火腿+肉松
那么这个就和我们的装饰模式很类似,动态的给煎饼添加一些额外的组合,
那么我们就来以煎饼来学习装饰模式:
根据定义思考:
- 需要基础类
- 是在基础类上添加职责
- 每一种食品都有名字和价格
下面就用代码来实现:
抽象构件:每一种食品都有名字和价格
public abstract class base {
//品种
public abstract String name();
//价格 这里就按照整数了
public abstract int price();
}
具体构件:煎饼类并继承公共类
public class Battercake extends base {
public String name() {
return "煎饼";
}
public int price() {
return 5;
}
}
装饰角色:
public class BattercakeDecorator extends Base {
private Base base;
//通过构造函数传递被修饰者
public BattercakeDecorator(Base base) {
this.base = base;
}
public String name() {
return this.base.name();
}
public int price() {
return this.base.price();
}
}
具体装饰类:鸡蛋和火腿
鸡蛋:
public class Egg extends BattercakeDecorator {
public Egg(Base base) {
super(base);
}
@Override
public String name() {
return super.name()+"+ 一个鸡蛋 ";
}
@Override
public int price() {
return super.price()+1;
}
}
火腿:
public class SausageDecorator extends BattercakeDecorator {
public SausageDecorator(Base base) {
super(base);
}
@Override
public String name() {
return super.name()+"+ 一根火腿 ";
}
@Override
public int price() {
return super.price()+2;
}
}
最终来测试一下代码:
public class BattercakeTest {
public static void main(String[] args) {
//原始
Base base ;
//创建煎饼
base = new Battercake();
//添加鸡蛋
base = new Egg(base);
//添加火腿
base = new SausageDecorator(base) ;
System.out.println(base.name() + " 总价:"+base.price());
}
}
运行结果:
煎饼 + 一个鸡蛋 + 一根火腿 总价:8
效果很明显:动态的扩展一个类的功能
解析:
注意:这里并不是直接在煎饼上面添加职责。
装饰模式角色说明:
- 抽象构件
是一个接口或者抽象类,其实就是最核心的对象 这里就是我们base抽象类 - 具体构件
需要装饰的对象 这里就是我们的煎饼类 - 装饰角色
实现接口或抽象方法,需要一个变量指向抽象构件 这里就是BattercakeDecorator 类 - 具体装饰角色
把最基础的东西装饰成另外的东西 这里具体装饰角色就是鸡蛋和火腿
应用场景:
- 需要扩展一个类的功能
- 需要动态的给一个对象添加功能
实际场景:比如我们的返回对象,有基础的,有分页的,有带集合的,有集合不带分页的 这样的场景是否可以用装饰模式来修饰呢?