1、定义
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
2、使用场景
小明要去约会见妹子,初次见面,不清楚对方到底是喜欢那种类型的男生,只能猜测可能是大叔控,可能是艺术控,也可能是文艺控,也可能是奶狗控,等等,对于每一种控都会存在衣服穿着上的不同,如何解决小明的穿搭问题。我们可以将大叔型男、文艺书生、奶油小生看作是一个具体的穿搭对象,将服饰作为一个抽象类,鸭舌帽子、衬衫、T恤,裤衩、西裤、休闲裤、红袜子、皮鞋、小白鞋、Nike运动鞋、作为具体的装饰类。为此我们就可以为小明定制多种穿搭风格啦。
3、代码结构UML图
人:ConcreteComponet定义了一个具体的对象,也可以给这个对象添加职责。
服饰:装饰抽象类,继承Componet,从外类来扩展Componet类的功能,但对于Componet来说,是无需知道Decorator的存在的。
大T恤、垮裤、破球鞋、西装、领带、皮鞋:CpmcretaDecorator就是具体的装饰对象,起到给Component添加职责的功能。
4、类的实现
(1)、Person(人类)
public class Person {
public Person() {
}
private String name;
public Person(String name) {
this.name = name;
}
public void show() {
System.out.println("装扮的" + name);
}
}
(2)、Finery(服饰类)
public class Finery extends Person {
protected Person component;
//打扮
public void decorate(Person component) {
this.component = component;
}
@Override
public void show() {
if (null != component) {
component.show();
}
}
}
(3)、BigTrouser、LeatherShoes、Sneakers、Suit、Tie、TShirts(具体服饰类)
public class BigTrouser extends Finery {
@Override
public void show() {
System.out.print("垮裤 ");
super.show();
}
}
public class LeatherShoes extends Finery {
@Override
public void show() {
System.out.print("皮鞋 ");
super.show();
}
}
public class Sneakers extends Finery {
@Override
public void show() {
System.out.print("破球鞋 ");
super.show();
}
}
public class Suit extends Finery {
@Override
public void show() {
System.out.print("西装 ");
super.show();
}
}
public class Tie extends Finery {
@Override
public void show() {
System.out.print("领带 ");
super.show();
}
}
public class TShirts extends Finery {
@Override
public void show() {
System.out.print("大T恤 ");
super.show();
}
}
5、客户端调用
public static void main(String[] args) {
Person xm = new Person("小明");
System.out.println("第一种装扮:");
Sneakers pqx = new Sneakers();
BigTrouser kk = new BigTrouser();
TShirts dtx = new TShirts();
pqx.decorate(xm);
kk.decorate(pqx);
dtx.decorate(kk);
dtx.show();
System.out.println("第二种装扮:");
LeatherShoes px=new LeatherShoes();
Tie ld=new Tie();
Suit xz=new Suit();
px.decorate(xm);
ld.decorate(px);
xz.decorate(ld);
xz.show();
}
输出结果:
第一种装扮:
大T恤 垮裤 破球鞋 装扮的小明
第二种装扮:
西装 领带 皮鞋 装扮的小明
6、总结
装饰模式是为已有的功能动态地添加更多功能的一种方式。
当系统需要新功能的时候,是向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为。
参考:《大话设计模式》