前言
装饰者模式属于结构型设计模式,它可以动态地为对象添加额外的只能,就这点来看,装饰者模式比生成子类更加灵活。既然是结构型设计模式,那么装饰者模式的结构优势体现在哪里呢?有一个组件类,有一个具体的组件类,这个具体的组件类就是要被装饰的对象,还有一个装饰者类,其继承了组件类,对于组件类来说不需要知道这个装饰者类对象的存在,因为装饰者对象真正发挥作用的对象是具体的组件类。要注意的是,组件类和装饰者类都是抽象类,为什么这么设计呢?这点其实很好理解,因为对于每一个具体的组件来说,可能装饰的花样不同,则具体的实现也就不同,把装饰者类设计成抽象类就可以把具体的装饰过程交给子类装饰者了,从而提高软件的灵活性。这同时也体现了依赖倒转原则,实现不应该依赖于细节而应该依赖于抽象。
ok,说了那么多还不如来一张装饰者模式的结构图:
现在,可以对装饰者模式有一个清晰的认识了。以穿衣打扮作为例子说明装饰者模式在编码中的应用:
编码实践
package rhwayfun;
public class DecoratorMode{
//abstract person
public abstract class Person{
//name
protected String name;
public Person(){}
public Person(String name){this.name = name;}
//show the appearance
public abstract void show();
}
//boy
public class Boy extends Person{
public Boy(String name ){super(name);}
public void show(){
System.out.println("I am a boy named " + name);
}
}
//girl
public class Girl extends Person {
public Girl(String name ){super(name);}
public void show(){
System.out.println("I am a girl named " + name);
}
}
//abstract decorator
public abstract class Finery extends Person{
protected Person person;
public void decorateComponent(Person person){
this.person = person;
}
public abstract void show();
}
//concrete decoratorA of Boy
public class TShirt extends Finery{
public void show(){
person.show();
System.out.println("dashing T-shirt");
}
}
//concrete decoratorB of Boy
public class Jeans extends Finery{
public void show(){
person.show();
System.out.println("fashoin Jeans");
}
}
//concrete decoratorB of girl
public class Skirt extends Finery {
public void show(){
person.show();
System.out.println("beautiful skirt");
}
}
//concrete decoratorB of girl
public class Hat extends Finery {
public void show(){
person.show();
System.out.println("white hat");
}
}
//concrete decoratorC of girl
public class HighHeeledShoes extends Finery {
public void show(){
person.show();
System.out.println("sexy high-heel shoes");
}
}
//test case
public static void main(String[] args){
DecoratorMode dm = new DecoratorMode();
Boy boy = dm.new Boy("xiaofan");
Girl girl = dm.new Girl("rhway");
Finery tshirt = dm.new TShirt();
Finery jeans = dm.new Jeans();
tshirt.decorateComponent(boy);
jeans.decorateComponent(tshirt);
jeans.show();
System.out.println("**********");
Finery skirt = dm.new Skirt();
Finery hat = dm.new Hat();
Finery highheeledshoes = dm.new HighHeeledShoes();
skirt.decorateComponent(girl);
hat.decorateComponent(skirt);
highheeledshoes.decorateComponent(hat);
highheeledshoes.show();
}
}
测试结果:
从上面的代码中可以体会到装饰者模式的使用方法。一般而言,如果当需要向新系统中添加新的功能的时候,可能需要添加新的字段、方法和逻辑,这样一般会增加复杂度。注意,这么说有一个前提,当新增加的功能不是核心功能,因为核心功能是系统运行必须增加的方法或者逻辑,这点复杂度的增加是必须得接受的。那么如果是非核心功能,那么如果一直都是添加在原有的类中就会使得类越来越臃肿,系统维护的难度会逐渐增加。那么怎么解决这个问题呢?根据设计模式中单一职责原则,类中的方法越来越多肯定不是一件好事,使用装饰者模式可以很好解决这个问题。装饰者模式把一要新增加的字段、方法和逻辑从原有的类中移除,并创建一个新的类,成为装饰者类。当系统需要这个方法的时候,就可以根据需要灵活地选用装饰者了。这样就把核心功能与装饰功能分开了,从而可以有效去除重复的逻辑代码。