装饰模式
定义:动态地给一个对象添加一些额外的职能,就增加功能来说,装饰模式比生成子类更为灵活。
举列子:衣服、帽子、鞋子等可以理解为对人的装饰。
"Component"是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责(不是必须的)。Decorator装饰抽象类,继承了Component,从外类来拓展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
实现例子:
Person类(ConcreteComponent)
/**
* 被装饰的类
*/
public class Person {
private String name;
public Person(String name){
this.name = name;
}
public Person(){}
//最终自己要执行的方法,增加的功能由其他装饰类去实现
public void show(){
System.out.println("装扮的" + name);
}
}
服饰类(Decorator)
/**
* 抽象装饰类(服装类),里面管理着被装饰类,可以给他装饰。
* 当前的类只能装饰一个,最顶层的被装饰类,是通过一层层去装饰的。跟俄罗斯套娃一样。
*/
public abstract class Finery extends Person{
protected Person component;
//打扮
public void decorate(Person component){
this.component = component;
}
@Override
public void show() {
if (component != null) {
component.show();
}
}
}
具体服饰类(ConcreteDecorator)
/**
* 具体装饰类(装饰人身上的T恤)
*/
public class TShirt extends Finery{
@Override
public void show() {
System.out.println("大T恤"); //先执行自己的方法
super.show(); // 再执行父类被装饰的类方法
}
}
/**
* 具体装饰类(装饰人身上的垮裤)
*/
public class BigTrouser extends Finery{
@Override
public void show() {
System.out.println("垮裤"); //先执行自己的方法
super.show(); //再执行父类中刚刚装饰进行的类方法
}
}
测试类
public class TestDecorator {
public static void main(String[] args) {
Person person = new Person("bruce"); //需要被装饰的人
TShirt tShirt = new TShirt();
BigTrouser bigTrouser = new BigTrouser();
//装饰的过程,又里到外,输出的时候又外到里
tShirt.decorate(person); //首先T恤装饰人
bigTrouser.decorate(tShirt); //垮裤装饰T恤,间接装饰了人
bigTrouser.show(); // 然后执行方法,从垮裤--》T恤--》人
}
}
上面各种随机搭配就会有随机输出了。
总结
装饰模式把每个要装饰的功能放在单独类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行是根据需要有选择地、按顺序地使用装饰功能包装对象了。