设计模式之装饰模式
1.什么是装饰模式?
- 官方的定义是:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。其实装饰模式就类似人穿衣服一样,装饰就类似于一个衣柜的效果,我们无需对人这个类进行修改,只需要对衣柜来添加衣服或者更换衣服就可以了。如果直接对人进行操作的的话,就违反了开放-封闭原则(开放-封闭原则指的是对软件实体【类、模块、函数等】是可以扩展的,但是不可以修改。)
- 装饰模式的结构图如下:
Component是定义一个对象接口,可以给这些对象动态的添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorater,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但是对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
2.如何来用装饰模式?
-我定义了一个人类,来表示我们要打扮的人。然后又增加一个服饰类,来管理衣服(类似衣柜),之后添加各种服饰。定义的这个例子中没有使用Component类,直接使用Decorator(FuShi.java)继承人类ConcreteComponent(Person.java)类。
public class Person {
//穿衣服的人名字
private String name;
public Person(){
//构造类型
}
public Person(String name){
this.name = name;
}
public void Show(){
System.out.println("装扮的:"+name);
}
}
public class FuShi extends Person{
protected Person person;
//打扮
public void Decorate(Person person){
this.person = person;
}
@Override
public void Show() {
if (person != null){
person.Show();
}
}
}
添加服饰(只添加T-shirt来表示,其他的代码类似,就不展示了。)
public class TShirts extends FuShi {
@Override
public void Show() {
System.out.println("大T-shirt");
super.Show();
}
}
UML图:
最后的输出结果:
public class Main {
public static void main(String[] args){
Person ld = new Person("李达");
Pant p = new Pant();
TShirts t = new TShirts();
Shoes s = new Shoes();
Cap c = new Cap();
Overcoat oc = new Overcoat();
//_________________^+^________________
System.out.println("第一种装扮:");
//装饰过程
p.Decorate(ld);
t.Decorate(p);
t.Show();
//_________________^+^________________
System.out.println("第二种装扮:");
//装饰过程
s.Decorate(ld);
c.Decorate(s);
oc.Decorate(c);
oc.Show();
}
}
最后的输出结果:
第一种装扮:
大T-shirt
衬衫
装扮的:李达
第二种装扮:
A new Overcoat
帽子
运动鞋
装扮的:李达
3.总结
装饰模式的作用:
1.可以为已有功能添加更多功能的一种方式。一般情况系使用的场景是在当系统需要新的功能的时候,我们会向旧的类中添加新的代码实现功能。这样做的问题在于它向主类中添加了新的字段,新的方法、新的逻辑,增加了主类的复杂程度。装饰模式提供的功能解决了这个问题,它把每个需要装饰的功能放在单独的类中,并让这个类包装它要装饰的对象,因此,当需要执行特定的装饰方案时,客户代码就可以有选择、按顺序的来使用装饰功能包装对象。
2.可以有效的把类的核心职责和装饰功能区别分开,可以去除相关类中的重复的装饰逻辑。但是在使用的时候,我们需要注意的是,保持装饰类之间的独立性,这样在装饰的时候,就可以随机选择不同的顺序进行了。
—结束—
^-^(不足之处请多多指教
代码地址GitHub地址