简介
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
适用环境
(1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
(2)处理那些可以撤消的职责。
(3)当不能采用生成子类的方法进行扩充时。
UML类图
描述
-
AbstractComponent(被装饰对象的抽象接口)
定义一个抽象对象接口。
-
Component(具体被装饰对象)
定义一个对象实现,可以给这些对象动态地添加职责。
-
AbstractDecorator(装饰者基类)
定义一个装饰对象的实现。
-
Decorator(具体装饰者)
具体的装饰对象,给内部持有的具体装饰一些职责。
实例(穿衣服)
interface People{
public void wear();
}
// 具体的对象,该对象将被附加一些额外的操作
class XM implements People{
public void wear() {
System.out.println("我要穿衣服");
}
}
// 装饰者基类,持有一个将要被装饰的接口对象的实例
class Decorator implements People{
private People people;
public Decorator(People people) {
this.people = people;
}
public void wear() {
people.wear();
}
}
// 具体的装饰者类,负责给增加附加的操作:穿衬衫
class DecoratorShirt extends Decorator{
public DecoratorShirt(People people) {
super(people);
}
public void wear() {
super.wear();
System.out.println("穿上衬衫");
}
}
// 具体的装饰者类,负责给增加附加的操作:穿外套
class DecoratorCoat extends Decorator{
public DecoratorTShirt(People people) {
super(people);
}
public void wear() {
super.wear();
System.out.println("穿上外套");
}
}
// 具体的装饰者类,负责给增加附加的操作:穿裤子
class DecoratorPants extends Decorator{
public DecoratorPants(People people) {
super(people);
}
public void wear() {
super.wear();
System.out.println("穿上裤子");
}
}
// 具体的装饰者类,负责给增加附加的操作:穿鞋子
class DecoratorShoes extends Decorator{
public DecoratorShoes(People people) {
super(people);
}
public void wear() {
super.wear();
System.out.println("穿上鞋子");
}
}
public class DecoratorTest {
public static void main(String[] args) {
Person xm = new XM();
//夏天
xm = new DecoratorShoes(new DecoratorPants(new DecoratorShirt(xm)));
xm.wear();
System.out.println("--------------");
//秋天要加一件
xm = new DecoratorShoes(new DecoratorPants(new DecoratorCoat(new DecoratorShirt(xm))));
xm.wear();
}
}
输出:
我要穿衣服
穿上衬衫
穿上裤子
穿上鞋子
-------------
我要穿衣服
穿上衬衫
穿上外套
穿上裤子
穿上鞋子
为什么使用装饰者而不使用继承?
- 装饰模式可以提供比继承更多的灵活性。装饰模式允许动态增加或删除一个装饰的功能。继承需要在此之前就要确定好对应的类。
- 像上面的例子里面一个人穿什么衣服,按照什么顺序来穿都是不定的,如果使用继承要考虑这么多情况就需要很多的类,然而使用装饰者就可以很方便的在使用的时候动态的创造组合不同的行为。
如何简化
具体问题具体分析:
- 只有一个具体构件角色:不需要角色基类
- 只有一个装饰角色:不需要装饰者基类