简介
装饰者模式又名包装(Wrapper)模式。装饰者模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰者模式动态地将责任附加到对象身上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
在装饰者模式中的角色有:
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
- 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
- 具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
![](https://img.haomeiwen.com/i16367972/8dcf6030c6b6d4bd.png)
实例介绍
现在是冬天,天气比较寒冷,大家下班了,都准备吃点热乎的。说到热乎的,那肯定是火锅比较给力了。火锅有各种底料,格式各样的配菜(是不是想想都流口水了)。
1.定义被装饰对象基类GuoDi(可以是抽象类也可以是接口)
public interface GuoDi {
/**
* 锅底的价格
* @return
*/
public float cost();
/**
* 锅底的名字
* @return
*/
public String name();
}
2.定义具体被装饰对象(也就是各种锅底,这里有两种)
鸳鸯锅底YuanYang
public class YuanYang implements GuoDi {
/**
* 锅底的价格
*
* @return
*/
@Override
public float cost() {
return 50.0f;
}
/**
* 锅底的名字
*
* @return
*/
@Override
public String name() {
return "鸳鸯锅底";
}
}
香辣锅底XiangLa
public class XiangLa implements GuoDi {
/**
* 锅底的价格
*
* @return
*/
@Override
public float cost() {
return 40.0f;
}
/**
* 锅底的名字
*
* @return
*/
@Override
public String name() {
return "香辣锅底";
}
}
3.定义装饰者抽象类PeiCai
public class PeiCai implements GuoDi {
private GuoDi guodi;
public PeiCai(GuoDi guodi) {
super();
this.guodi = guodi;
}
/**
* 锅底的价格
*
* @return
*/
@Override
public float cost() {
return guodi.cost();
}
/**
* 锅底的名字
*
* @return
*/
@Override
public String name() {
return guodi.name();
}
}
4.定义具体的装饰者对象(这里也是定义两个)
麻辣牛肉MaLaNiuRou
public class MaLaNiuRou extends PeiCai {
public MaLaNiuRou(GuoDi guodi) {
super(guodi);
}
@Override
public float cost() {
return super.cost()+60f;
}
@Override
public String name() {
return super.name()+"+麻辣牛肉";
}
}
豆腐皮DouFuPi
public class DouFuPi extends PeiCai{
public DouFuPi(GuoDi guodi) {
super(guodi);
}
@Override
public float cost() {
return super.cost()+20.0f;
}
@Override
public String name() {
return super.name()+"+豆腐皮";
}
}
5.创建一个测试类Test
public class Test {
public static void main(String[] args) {
//点个香辣锅底
GuoDi guodi = new XiangLa ();
//来个麻辣牛肉
MaLaNiuRou niurou = new MaLaNiuRou(guodi);
//再来一个豆腐皮
DouFuPi douFuPi = new DouFuPi(niurou);
System.out.println("您点了"+douFuPi.name());
System.out.println("共消费"+douFuPi.cost());
}
}
输出一下我们的结果:
![](https://img.haomeiwen.com/i16367972/d8d0031a83c962ce.jpg)
总结
装饰者模式的优缺点
装饰模式的优点
(1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
(2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
装饰模式的缺点
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
装饰者模式在Java IO流中的应用
由于Java I/O库需要很多性能的各种组合,如果这些性能都是用继承的方法实现的,那么每一种组合都需要一个类,这样就会造成大量性能重复的类出现。而如果采用装饰者模式,那么类的数目就会大大减少,性能的重复也可以减至最少。因此装饰者模式是Java I/O库的基本模式。(这里就不在多做赘述,后面再做详细介绍)。
网友评论