结构性模式之-装饰者模式
简介
装饰者模式主要是用来动态拓展当前类的功能
,用不同的方式优化代替继承的方式导致子类膨胀的问题。同时又不会修改该类与其它拓展类的本身功能。
常用的装饰者模式有java中的io
//典型的将字节流的功能拓展到了字符流
InputReader reader = new InputStreamReader(new FileInputStream(new File("/path")),"UTF-8")
reader.read()
1 思考
- 奶茶
- 原味奶茶
- 珍珠奶茶
- 椰果奶茶
- 珍珠椰果奶茶
- 柠檬茶
- 原味柠檬茶
- 金桔柠檬茶
假如奶茶店最开始菜单是如上的,现在需要添加1个配料“红豆”,现在客户要点
- 红豆珍珠奶茶
- 红豆椰果奶茶
- 红豆珍珠椰果原味金桔奶柠檬茶…
如果通过继承的方式,会产生很多个子类,导致难以维护,我们可以通过包装者
的方式来进行优化
- 茶 => (奶(茶)) => (珍珠(奶(茶))) => (红豆(珍珠(奶(茶))) )…层层封装,随意搭配
2 封装者模式图解
3 封装者模式具体实现
3.1 具体代码类
HongDou --红豆配料
JinJu --金桔配料
MilkTea --具体的奶茶类
NingMengTea --具体的柠檬茶 类
Tea --抽象的茶类,也可以是接口
TestMain --测试程序入口
YeGuo --椰果
ZhenZhu --珍珠
ZhuangShiZhe --装饰者抽象类,继承自Tea,同时可以使用其它Tea的功能,层层包装
3.2 具体代码实现
Tea
public abstract class Tea {
private String name = "茶";
//获取当前茶的名字
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//获取当前茶的总价格
public abstract int price();
}
MilkTea
//这是抽象类Tea的具体实现类
public class MilkTea extends Tea {
public MilkTea() {
setName("奶茶");
}
@Override
public int price() {
return 5;
}
}
NingMengTea
public class NingMengTea extends Tea {
public NingMengTea(){
setName("柠檬茶");
}
@Override
public int price() {
return 8;
}
}
ZhuangShiZhe
//这是用来装饰Tea的配料,也继承来自Tea
public abstract class ZhuangShiZhe extends Tea{
//将tea作为成员变量,可以在子类构造器中使用tea的属性
Tea tea;
}
HongDou
public class HongDou extends ZhuangShiZhe {
public HongDou(Tea tea) {
this.tea = tea;
}
//奶茶名字就是简单的拼接
@Override
public String getName() {
return "红豆" + tea.getName();
}
//奶茶九个就是当前配料的价格+需要被添加配料的奶茶的价格
@Override
public int price() {
return 2 + tea.price();
}
}
JinJu
public class JinJu extends ZhuangShiZhe {
public JinJu(Tea tea) {
this.tea = tea;
}
@Override
public String getName() {
return "金桔" + tea.getName();
}
@Override
public int price() {
return 3 + tea.price();
}
}
YeGuo
public class YeGuo extends ZhuangShiZhe {
public YeGuo(Tea tea) {
this.tea = tea;
}
@Override
public String getName() {
return "椰果" + tea.getName();
}
@Override
public int price() {
return 3 + tea.price();
}
}
ZhenZhu
public class ZhenZhu extends ZhuangShiZhe {
public ZhenZhu(Tea tea) {
this.tea = tea;
}
@Override
public String getName() {
return "珍珠" + tea.getName();
}
@Override
public int price() {
return 5 +tea.price();
}
}
TestMain