截止目前为止,我已经学了四个设计模式了,首先回顾一下这几天学习设计模式的感悟,第一个接触的当然就是单例模式了,单例模式由于将构造方法私有化,因此在类的外面不能创造该类的对象,那么问题来了,那我们就在类的里面得到该类的对象,且该类的对象而且是唯一的,就是这样。接着学习了责任链模式,责任链模式不用多说,就是一条链式结构,该模式的核心思想就是将职责沿着一条链式结构进行传递。接着就是原型模式,原型模式感觉学起来还是有点复杂,就是使用Java提供的接口函数cloneable函数,实现其中的方法clone方法,今天接触的是装饰模式,对我之前的设计模式不太了解的同学可以观看我之前的博客。
今天我们步入正题吧,装饰模式
一、装饰模式的定义
接下来我们首先谈一下装饰模式的概念,如果我们想要对一个类的功能进行扩展,一般采用继承的方式,但是在Java语言中,是不支持的多继承的,那么问题来了,我们就需要使用装饰模式,装饰模式是为了解决多继承一种思路。我们将会在接下来的URL图中详细观看。
Component(抽象构件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作。
● ConcreteComponent(具体构件):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
● Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
● ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。
这里借用刘伟作者的URL图,希望作者不要介意,推荐大家可以学习刘伟的设计模式那本书,非常值得学习。二、具体事例
接下来我用代码为大家做简要介绍
欲开发了一个数据加密模块,可以对字符串进行加密。最简单的加密算法通过对字母进行移位来实现,同时还提供了稍复杂的逆向输出加密,还提供了更为高级的求模加密。用户先使用最简单的加密算法对字符串进行加密,如果觉得还不够可以对加密之后的结果使用其他加密算法进行二次加密,当然也可以进行第三次加密。试使用装饰模式设计该多重加密系统。
那么我们首先设计一个抽象类作为根基
package director;
public abstract class EncryptComponet {
public abstract void encrypt();
}
这个就是抽象类,装饰类继承于他
package director;
public class ConcreteEncrypt extends EncryptComponet {
private EncryptComponet encryptComponet;
public ConcreteEncrypt(EncryptComponet encryptComponet) {
super();
this.encryptComponet = encryptComponet;
}
public void encrypt() {
// TODO Auto-generated method stub
encryptComponet.encrypt();
}
}
大家看到了没有,我们传递了抽象的父类进来,作为对象使用,接下来我们下装饰的具体子类实现
package director;
public class TranslateEncrypt extends ConcreteEncrypt {
public TranslateEncrypt(EncryptComponet encryptComponet) {
super(encryptComponet);
// TODO Auto-generated constructor stub
addTranslateEncrypt();
}
private void addTranslateEncrypt() {
// TODO Auto-generated method stub
System.out.println("移动加密");
}
}
这是对数据的一次加密,我们还可以继续继承装饰类
package director;
public class ReversEncrypt extends ConcreteEncrypt {
public ReversEncrypt(EncryptComponet encryptComponet) {
super(encryptComponet);
// TODO Auto-generated constructor stub
addReservesEncrypt();
}
private void addReservesEncrypt() {
// TODO Auto-generated method stub
System.out.println("反向加密");
}
}
哈哈,不用多说了,接下来是三次加密的代码
package director;
public class SuperEncrypt extends ConcreteEncrypt {
public SuperEncrypt(EncryptComponet encryptComponet) {
super(encryptComponet);
// TODO Auto-generated constructor stub
addSuperEncrypt();
}
private void addSuperEncrypt() {
// TODO Auto-generated method stub
System.out.println("最高加密算法");
}
}
package director;
public class RawData extends EncryptComponet {
public void encrypt() {
// TODO Auto-generated method stub
System.out.println("这是要发送的数据");
}
}
package director;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
EncryptComponet ss,abc1,abc2,abc3;
ss = new RawData();
abc1 = new TranslateEncrypt(ss);
//abc1.encrypt();
abc2 = new ReversEncrypt(abc1);
//abc2.encrypt();
abc3 = new SuperEncrypt(abc2);
abc3.encrypt();
}
}
上面就是所有代码的实现
由于刚开始写技术博客,很多地方写的不到位,望大家多多指导
三、装饰模式使用场景
在以下情况下可以考虑使用装饰模式:
(1) 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
(2) 当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种扩展或者扩展之间的组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类已定义为不能被继承(如Java语言中的final类)。