装饰者模式
装饰者模式是对原有功能类增加一些新的功能(行为)。但是为原有功能类增加新的功能行为,继承或组合也能做法,为什么要使用装饰者模式呢?这是因为要对原有功能类动态地同时增加多个功能行为(包括相同行为或不同行为),单独使用继承或组合实现将产生大量的子类(“类爆炸”),而使用装饰者模式则可以在保持良好的扩展性的同时避免“类爆炸”情况的出现。
星巴克咖啡问题
咖啡问题
装设者模式解决此问题
原理
代码实现
装饰者模式,是将即符合装饰者也符合被装饰者的属性给抽象出来,被装饰者通过继承来实现,装饰者不仅要继承还要聚合此(一层一层的套娃)
被装饰者
/**
* @program: learn_day01
* @description: 被装饰者(这里面定义了最终所需要的属性与行为)
* @author: wfg
* @create: 2021-05-11 08:47
*/
@Data
public abstract class Drink {
/**
* @Description: 描述
* @Author: wfg
*/
public String desc;
/**
* @Description: 价格
* @Author: wfg
*/
public float cost= 0.0f;
/**
* @Description: 行为
* @Author: wfg
*/
public float cost(){
return cost;
}
}
被装饰者所需要的东西
/**
* @program: learn_day01
* @description: 咖啡/重写行为,用于自己(这一层相当于业务逻辑部分)
* @author: wfg
* @create: 2021-05-11 08:49
*/
public class Coffee extends Drink{
@Override
public float cost(){
return super.cost();
}
}
实体
/**
* @program: learn_day01
* @description: coffee的子类
* @author: wfg
* @create: 2021-05-11 09:11
*/
public class CatShirt extends Coffee{
public CatShirt(){
setCost(5.0f);
setDesc("猫屎咖啡");
}
}
..........................................
/**
* @program: learn_day01
* @description: coffee的子类
* @author: wfg
* @create: 2021-05-11 08:53
*/
public class QueChao extends Coffee{
/**
* @Description:构造器用于属性赋值
* @Author: wfg
*/
public QueChao(){
setCost(2.3f);
setDesc("雀巢咖啡");
}
}
**装饰者实现方式是通过 递归的思想 这次的最终品=上一次的终品(聚合实现)+这次所选的调料(本身)
**
/**
* @program: learn_day01
* @description: 装饰者 需要继承drink还需要聚合drink,是通过在原来的caffee上面加料组成新的caffee
* @author: wfg
* @create: 2021-05-11 08:57
*/
public class Decorate extends Drink{
/**
* @Description: 聚合原来咖啡
* @Author: wfg
*/
private Drink drink;
public Decorate (Drink drink){
this.drink=drink;
}
/**
* @Description: 价格变为自己本身的价钱加上原来的价格
* @Author: wfg
*/
@Override
public float cost(){
return super.getCost()+ drink.cost();
}
@Override
public String getDesc(){
return super.desc+" "+super.getCost()+"&&"+ drink.desc;
}
}
实现、
/**
* @program: learn_day01
* @description: 调味品
* @author: wfg
* @create: 2021-05-11 09:08
*/
public class Milk extends Decorate{
public Milk(Drink drink) {
super(drink);
setDesc("牛奶哦");
setCost(0.5f);
}
}
最终测试
/**
* @program: learn_day01
* @description:点一份雀巢,加牛奶
* @author: wfg
* @create: 2021-05-11 09:20
*/
public class Main {
public static void main(String[] args) {
//点一份雀巢
Drink que=new QueChao();
System.out.println("雀巢描述:"+que.getDesc());
que.cost();
System.out.println("雀巢价格"+que.cost());
//加牛奶
Drink milk =new Milk(que);
System.out.println("牛奶雀巢描述:"+milk.getDesc());
milk.cost();
System.out.println("牛奶雀巢价格:"+milk.cost());
}
}
装饰者模式与桥接模式区别
1。桥接模式中所说的分离,其实是指将结构与实现分离(当结构和实现有可能发生变化时)或属性与基于属性的行为进行分离;而装饰者只是对基于属性的行为进行封闭成独立的类。
2。桥接中的行为是横向的行为,行为彼此之间无关联;而装饰者模式中的行为具有可叠加性,其表现出来的结果是一个整体,一个各个行为组合后的一个结果。