文章目录
-
- 1. 装饰者模式的简介
- 2. 实例讲解
- 3. 在java.io中的应用
1. 装饰者模式的简介
装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
2. 实例讲解
这里以吃火锅为例进行讲解:
说明:火锅是一个抽象类,锅底和菜品都继承了它,然后在点了一个具体的锅底以后,可以添加菜品,由于可以添加多个菜品,这个时候就得考虑怎么样设计我们的代码了,所以有了今天的主角==>装饰者模式
如上所述,锅底一个就ok,而菜品可以有多个,所以我们选择将菜品作为装饰者,而火锅作为被装饰者,具体代码如下
火锅、锅底、菜品的具体代码:
/**
* 抽象类火锅
*/
public abstract class HotPot {
private String des;
private float price;
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public abstract float cost();
}
// 锅底
public class Bottom extends HotPot {
@Override
public float cost() {
return super.getPrice();
}
}
// 菜品 装饰者
public class Dishes extends HotPot {
// 引入被装饰者
private HotPot hotPot;
public Dishes(HotPot hotPot) {
this.hotPot = hotPot;
}
@Override
public float cost() {
// 计算价格
return super.getPrice() + hotPot.cost();
}
@Override
public String getDes() {
return des + " " + getPrice() + " " + "&&" + " " + hotPot.getDes();
}
}
锅底的三个品种:
public class Spicy extends Bottom {
public Spicy() {
setDes("麻辣锅底");
setPrice(6.0f);
}
}
public class ThreeFresh extends Bottom{
public ThreeFresh() {
setDes("三鲜锅底");
setPrice(5.0f);
}
}
public class ClearSoup extends Bottom {
public ClearSoup() {
setDes("清汤锅底");
setPrice(4.0f);
}
}
菜品的三种:
public class Beef extends Dishes {
public Beef(HotPot hotPot) {
super(hotPot);
setDes("牛肉");
setPrice(12.0f);
}
}
public class Pork extends Dishes{
public Pork(HotPot hotPot) {
super(hotPot);
setDes("猪肉");
setPrice(11.0f);
}
}
public class Mutton extends Dishes {
public Mutton(HotPot hotPot) {
super(hotPot);
setDes("羊肉");
setPrice(10.0f);
}
}
开始吃了:
public class Eat {
public static void main(String[] args) {
// 1.点一份三鲜锅
HotPot hotPot = new ThreeFresh();
System.out.println("费用:" + hotPot.getPrice() + " 描述:" + hotPot.getDes());
// 2.加入一份牛肉
hotPot = new Beef(hotPot);
System.out.println("加入一份牛肉之后费用:" + hotPot.cost() + " 描述:" + hotPot.getDes());
// 3.又加入一份猪肉
hotPot = new Pork(hotPot);
System.out.println("加入一份牛肉之后又加入一份猪肉费用:" + hotPot.cost() + " 描述:" + hotPot.getDes());
}
}
运行结果如图:
简单总结一下:装饰者模式是建立在继承之上的,但是比继承更加灵活,从以上代码可以看到,可以非常方便动态的增加我们的菜品
3. 在java.io中的应用
首先看一幅图:
再结合源码:
由此我们可以发现,
InputStream
使用了装饰者模式,其中
InputStream
是被装饰者,
FilterInputStream
是装饰者,而
ByteArrayInputStream
等就类似于我们的锅底,
DataInputStream
等就类似于我们的菜品