image装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
装饰模式中的角色:
- Component:抽象组件,可以是接口或是抽象类,被装饰的最初始的对象。
- ConcreteComponent:组件具体实现类,Component 的具体实现类,被装饰的具体对象。
- Decorator:抽象装饰者,从外类来拓展 Component 类的功能,但对于 Component 来说无须知道 Decorator 的存在。在它属性中比如有一个 private 变量指向 Component 抽象组件。
- ConcreteDecorator:装饰者的具体表现类。
装饰模式的简单实现
(1)抽象组件
public abstract class Person {
public abstract void show();
}
(2)组件具体实现类
public class Man extends Person {
@Override
public void show() {
System.out.println("打扮男生");
}
}
(3)抽象装饰者
public abstract class Finery extends Person {
private Person person;
public void setPerson(Person person) {
this.person = person;
}
@Override
public void show() {
person.show();
}
}
(4)装饰者具体实现类
public class TShirts extends Finery {
@Override
public void show() {
super.show();
System.out.println("T-Shirts");
}
}
public class BigTrouser extends Finery {
@Override
public void show() {
super.show();
System.out.println("BigTrouser");
}
}
(5)客户端调用
public class Client {
public static void main(String[] args) {
Man man = new Man();
TShirts tShirts = new TShirts();
BigTrouser bigTrouser = new BigTrouser();
tShirts.setPerson(man);
bigTrouser.setPerson(tShirts);
bigTrouser.show();
}
}
(6)输出
打扮男生
T-Shirts
BigTrouser
装饰模式的使用场景
使用场景:
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加在职责。
需要动态地给一个对象增加功能,这些功能可以动态地撤销。
当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时。
装饰模式的优缺点
优点:
通过组合而非继承的方式,动态地扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
有效避免了使用继承的方式扩展对象功能而带来的灵活性差、子类无限扩张的问题。
具体组件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体组件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合"开放封闭原则"。
缺点:
因为所有对象均继承于 Component,所以如果 Component 内部结构发生改变,则不可避免地影响所有子类(装饰类和被装饰类)。如果基类变化,则势必影响对象的内部。
比继承更加灵活机动的特征,也同时意味着装饰模式比继承更加易于出错,排错也很困难。对于多次装饰的对象,调试时寻找错误困难需要逐级排查,较为烦琐。所以,只在必要的时候使用装饰模式
装饰层数不能过多,否则会影响效率。
网友评论