文章目录
前言
文章内容主要参考了刘伟主编的《设计模式(第2版)》,同时也结合了自己的一些思考和理解,希望能帮到大家。
本篇讲解装饰模式,和组合模式一样分成两种类型,一个是透明装饰模式,一个是不透明装饰模式,仔细观察的人可能会发现好像两个设计模式有点相像,但是说实话两个思想却是相差很远,我个人觉得如果你是学会模式的内在思考方式,学完后你并不会混淆而说像。(因为这个相像其实一开始我没发现的,是老师说有同学学到这觉得很像,我仔细一看确实外貌挺像的,但是除了外貌就再无其他了。。。这也说明其实有些同学学的时候更多看在了外在的东西,没学到骨子里)。
最后学完,看大家自行去理解区分两个模式了,里面确实有很多相近的东西。
正文
一、定义
装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活,是一个对象结构型模式。
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,可以在不需要创建更多子类的情况下,让对象的功能得以扩展。是一种用于替代继承的技术,它通过一种无须定义子类的方式给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系,同时引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩展原有类的功能。
二、情景假设
变形金刚在变形之前是一辆汽车,它可以在陆地上移动。当它变成机器人之后除了能够在陆地上移动之外,还可以说话;如果需要,它还可以变成飞机,除了在陆地上移动还可以在天空中飞翔。
情景大概是由汽车拓展成机器人和飞机时,该怎么处理?
三、情景分析
关于上面情景的类图(具体分析在下面)
首先我们很容易想到的是,既然要拓展嘛,那就先继承汽车拥有汽车的方法,然后再在继承类上加上机器人特定的方法,那就是机器人啦,加上汽车特有的方法,那就是汽车类啦。一切都很简单,但是论实际上,增加一种拓展方式,很可能增加非常多的是实现类,这将会让系统变得非常的庞大(树形的深度越来越深,互相耦合程度更加庞大)。其次可能还会牵扯到多继承的问题(因为有些类可能会继承多个需要拓展的),同时使用继承也是破化了类的封装性
所以装饰模式所采用的方法就是利用关联代替继承,这样一来降低了继承所导致的耦合度增大,同时,软件维护上,关联关系的松耦合性,使得系统更加的容易维护。树形的层数较少,在于横向的拓展,拓展起来更加方便,还能够很好的实现运行时动态拓展。
所以先定义抽象类
//抽象构件类
public abstract class Transform
{
public abstract void move();
}
具体已有的汽车类
//汽车Car
public final class Car extends Transform{
public void Car(){
System.out.println("变形金刚是一辆车!");
}
public void move(){
System.out.println("在陆地上移动!");
}
}
细心的同学发现了,我还定义了final,声明着这不能继承拓展增加难度,这样其实我们就不得不利用关联的方式了。
定义一个装饰类,装饰类同样继承抽象类Transform,因为装饰类的本质我们不能忘,我们只是对原有存在的进行拓展,而对于客户端而言应当还是能当作之前的情况继续使用,为了实现统一的使用,实现同一的抽象类客户端便能够可以无视细节。在这个时候我们可以增加需要被拓展的类作为属性关联起来。
//装饰类Changer
public class Changer extends Transform{
private Transform t ;
public void add(Transform t){
this.t = t;
}