一、引言
9月30号上映,《我和我的祖国》这个电影,小编不知道你们看了没,还挺不错的。
其中讲述了新中国成立、中国女排、香港回归、首颗原子弹爆炸等等历史性的事件,小编再一次体会到中国的强大。
国庆节假期现在是第四天了,去年这个时候小编还记得再写redis相关操作,年复一年。
二、装饰者定义
结构型设计模式,动态的将新功能附加到对象上,在对象功能扩展方面,他比继承更加有弹性,装饰者模式也体现了开闭原则。
那装饰者有什么优点呢? 可能刚一开始说还看不太明白,看完具体案例分析实现,再回头来看,是否理解。
1、扩展一个类的功能,或者给一个类增加附加职责。
2、通过这些不同的装饰者,可以使被装饰者实现不同的效果。
3、符合开闭原则,可以在不改变原有类的情况下,给个对象添加新的功能。
三、装饰者案例分析
你们喜欢吃手抓饼嘛?
小编吃手抓饼喜欢加培根和肉松,再外加一瓶牛奶,完美解决早餐。
那就以这个生活为案例,假设现在有一款手抓饼的产品,可以加多份不同的配料,然后计算最后的价格。
小伙伴们可以先想想,如果要你现在设计这么一个功能,你会怎么去设计?
注意:一个手抓饼可以加两份培根,一份肉松等等,还需要注意程序的可扩展性、维护性。
装饰者就比较适合这种场景来使用,下面进行角色分析
1、抽象产品:被装饰者基类,用来定义被装饰者的行为和方法
2、被装饰者:具体的装饰者类,可以动态添加新的功能(比如一个手抓饼可以加鸡蛋、火腿等等)。
3、抽象装饰者:需要聚合或者组合具体被装饰者,还需要继承或者实现抽象产品
4、装饰者:持有被装饰者对象,并且进行新功能的添加
四、装饰者案例实现
步骤一:首先我们需要创建产品,产品是主要内容,装饰是其次(首先你要有煎饼果子可以卖,才可以加火腿之类的)。
/**
* @Auther: IT贱男
* @Date: 2019/8/21 13:54
* @Description: 产品抽象类
*/
public interface Apancake {
/**
* 产品描述
* @return
*/
String getDesc();
/**
* 产品价格
* @return
*/
int cost();
}
/**
* @Auther: IT贱男
* @Date: 2019/8/21 13:56
* @Description: 被装饰者 - 煎饼果子
*/
public class BatterCake implements Apancake {
@Override
public String getDesc() {
return "煎饼果子";
}
@Override
public int cost() {
return 5;
}
}
步骤二:现在具体产品有了,那么光一个煎饼果子也不够吃呀,商家还提供了可以加火腿、鸡蛋这个配料。
/**
* @Auther: IT贱男
* @Date: 2019/8/21 13:57
* @Description: 抽象装饰者 - 实现产品接口
*/
public class AbstractDecorate implements Apancake {
// 聚合一个具体的被装饰者
protected Apancake apancake;
public AbstractDecorate(Apancake apancake) {
this.apancake = apancake;
}
@Override
public String getDesc() {
// 调用被装饰者的方法
return this.apancake.getDesc();
}
@Override
public int cost() {
// 调用被装饰者的方法
return this.apancake.cost();
}
}
/**
* @Auther: IT贱男
* @Date: 2019/8/21 14:02
* @Description: 火腿肠装饰者 -> 继承抽象抽象装饰者
*/
public class SausageDecorate extends AbstractDecorate {
public SausageDecorate(Apancake apancake) {
super(apancake);
}
@Override
public String getDesc() {
// 首先需要调用父类的方法,获取原本结果的基础之上,新增新功能
return super.getDesc() + "加一个火腿肠加两元";
}
@Override
public int cost() {
// 首先需要调用父类的方法,获取原本的价格,加一根火腿的价格
return super.cost() + 2;
}
}
/**
* @Auther: IT贱男
* @Date: 2019/8/21 13:59
* @Description: 鸡蛋装饰者 -> 继承抽象抽象装饰者
*/
public class EggDecorate extends AbstractDecorate {
public EggDecorate(Apancake apancake) {
super(apancake);
}
@Override
public String getDesc() {
return super.getDesc() + "加一个鸡蛋一元";
}
@Override
public int cost() {
return super.cost() + 1;
}
}
步骤三:测试,现在来了一个客人,需要一个加鸡蛋、火腿的煎饼果子。 原本只是一个普通的煎饼果子,经过装饰者这么一操作之后,就变得不普通了。
/**
* @Auther: IT贱男
* @Date: 2019/8/21 14:03
* @Description:
*/
public class Test {
public static void main(String[] args) {
// 商家先做一个煎饼果子出来
Apancake batterCake = new BatterCake();
System.out.println(batterCake.getDesc() + " 价格:" + batterCake.cost());
System.out.println("-------------------------");
// 把做出来的煎饼果子加鸡蛋
batterCake = new EggDecorate(batterCake);
System.out.println(batterCake.getDesc() + " 价格:" + batterCake.cost());
// 把已经加好鸡蛋的煎饼果子,再加一个火腿
System.out.println("-------------------------");
batterCake = new SausageDecorate(batterCake);
System.out.println(batterCake.getDesc() + " 价格:" + batterCake.cost());
}
}
煎饼果子 价格:5
-------------------------
煎饼果子加一个鸡蛋一元 价格:6
-------------------------
煎饼果子加一个鸡蛋一元加一个火腿肠加两元 价格:8
三、装饰者模式和桥接模式区别
桥接模式的定义是将抽象与实现分离(用组合聚合的方式,而不是使用继承),使得两者可以独立变化,可以减少创建新的类。这样看起来和装饰者模式差不多,但是两者还是有一些区别。
1、桥接模式中所指的分离,是将抽象和实现分离,而装饰者只是基于属性的行为进行封装成独立的类。
2、桥接模式中的行为之间是没有关联的,而装饰者模式中的行为具有可叠加性,其表现出来的结果是一个整体。
3、两者都可以减少子类过多的问题。
转载:https://blog.csdn.net/weixin_38111957/article/details/102060099