定义
装饰者模式(DecoratorPattern):对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能。
相关角色
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接受附加责任的对象;
- 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类;
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口;
- 具体装饰(ConcreteDecorator)角色:负责给构件对象 ”贴上“附加的责任。
解决问题
动态地将责任附加到对象身上,比继承更具有弹性。
UML类图
decorator.pngComponent
public interface Component {
void sampleMethod();
}
Decorator
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void sampleMethod() {
// 委派给构件
component.sampleMethod();
}
}
ConcreteComponent
public class ConcreteComponent implements Component {
@Override
public void sampleMethod() {
System.out.println("I'm ConcreteComponent");
}
}
ConcreteDecorator
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void sampleMethod() {
//写相关的业务代码
super.sampleMethod();
addFunction();
}
public void addFunction() {
System.out.println(" add Function ConcreteDecorator");
}
}
例子
在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类)、AccessoriesPhone(挂件手机类)等,这样就会导致 ”子类爆炸“问题,为了解决这个问题,我们可以使用装饰者模式来动态地给一个对象添加额外的职责。
类图
decorator_phone.pngPhone
public abstract class Phone {
public abstract void print();
}
Decorator
public abstract class Decorator extends Phone {
Phone phone;
public Decorator(Phone phone) {
this.phone = phone;
}
@Override
public void print() {
if (phone != null)
phone.print();
}
}
XiaoMiPhone
public class XiaoMiPhone extends Phone {
@Override
public void print() {
System.out.println("小米手机");
}
}
Accessories
public class Accessories extends Decorator {
public Accessories(Phone phone) {
super(phone);
}
@Override
public void print() {
super.print();
addAccessories();
}
public void addAccessories() {
System.out.println("我是带挂件的手机");
}
}
优缺点
优点:
- 装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活;
- 通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合;
- 装饰者模式有很好地可扩展性。
缺点:
- 装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。
延伸
使用场景
下面让我们看看装饰者模式具体在哪些情况下使用,在以下情况下应当使用装饰者模式:
-
需要扩展一个类的功能或给一个类增加附加责任;
-
需要动态地给一个对象增加功能,这些功能可以再动态地撤销;
-
需要增加由一些基本功能的排列组合而产生的非常大量的功能。
网友评论