定义
动态的给一个对象参加额外的职责。就添加功能来说,装饰器模式比生成子类更加灵活。
本质
动态组合,动态是手段,组合是目的。
登场角色
-
Component
增加功能时的核心角色,组件对象的接口,可以给这些对象动态的添加功能。
-
ConcreteComponent
实现组件接口,具体的组件对象,通常是被装饰器修饰的原始对象,可以给这个对象添加职责。
-
Decorator(装饰物)
所有装饰器的抽象父类,实现了与Component相同的接口,并持有一个被装饰的对象。
-
ConcreteDecorator(具体的装饰物)
实际的装饰物对象,实现了向被装饰器对象添加的功能。
示例代码
/**
* 抽象组件类
*/
public abstract class Person {
public abstract void dressed();
}
/**
* 需要被装饰的原始对象
*/
public class Boy extends Person{
@Override
public void dressed() {
System.out.print("穿了衬衫");
}
}
/**
* 装饰物
*/
public abstract class PersonCloth extends Person{
private Person person;
public PersonCloth(Person person) {
this.person = person;
}
@Override
public void dressed() {
person.dressed();
}
}
/**
* 具体的装饰物对象1
*/
public class ExpensiveCloth extends PersonCloth{
public ExpensiveCloth(Person person) {
super(person);
}
/**
* 穿短袖
*/
private void dressShirt(){
System.out.println("穿短袖");
}
/**
* 穿皮衣
*/
private void dressLeather(){
System.out.println("穿皮衣");
}
@Override
public void dressed() {
super.dressed();
dressShirt();
dressLeather();
}
}
/**
* 具体的装饰物2
*/
public class CheapCloth extends PersonCloth{
public CheapCloth(Person person) {
super(person);
}
/**
* 穿短裤
*/
private void dressShorts(){
System.out.println("穿短袖");
}
@Override
public void dressed() {
super.dressed();
dressShorts();
}
}
运行结果
穿上昂贵的衣服
穿了衬衫穿短袖
穿皮衣
=============
穿上便宜的衣服
穿了衬衫穿短袖
功能
动态的为对象添加功能,并且是从对象外部来给对象添加功能,相当于是改变了对象的外观。
优点
- 比继承更灵活。
- 更容易复用功能。
- 简化高层定义,可以通过组合装饰器的方式,为对象添加任意多的功能。因为在进行高层定义的时候,可以不用把所有的功能都定义出来,而只定义最基本的就可以了。
缺点
- 会产生很多细粒度的对象。
何时使用
- 如果需要在不影响其他对象的情况下,以动态的透明的方式为对象添加功能,可以使用装饰器模式。
- 如果不适合使用子类来进行扩展,可以考虑使用装饰器模式,因为装饰器模式使用的是对象组合的方式,即装饰物对象持有被装饰对象的引用。
网友评论