从这一阶段开始讲述软件设计模式,我也不再讲GoF的神奇历史,直接进入正题。在进行模式讲解的同时,对于本人来说,一方面也是进行了复习,另一方面也是通过讲解使自己对这些模式的使用上达到一个更加理解的层次。搞软件的朋友都知道,在进行开发过一段时间后,会发现自己大学里学习的基础课很重要。而目前很多朋友对软件的理解都非常肤浅,只知道增删改查,试用这样的程序员能存活多久,思考很重要,学习很重要,理解很重要,领悟更重要。让浮燥的程序员回归理性吧,模式可能让浮燥的心情得到净化,在模式中进行思考,在模式中进行领悟吧。
第一讲是装饰器。当初我在学装饰器模式的时候总是感觉似懂非懂,一直没有真正理解。其实装饰器也叫油漆工模式,再加上在我们的java类库中有很多是实现了装饰器模式的类。比方说:在读取文件时
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
这其实就是一个decorator模式。因为针对File的读取方式有很多,如果每种都要采用继承的方法,那么会产生很多的子类,那样显然是很烦的。
装饰器也称为油漆工模式。它的目的就是给一个对象动态地添加一些功能。就像是给对象刷了一层漆,使这个对象更加丰富,而不是通过继承来增加功能。而这些功能的添加是动态的运行期的,当然这里的动态并不是像aop中的引介introductor,大家不要混淆。
在我们的项目中,经常会遇到日志的情况。大凡我们会定义一个log接口就像下面。
public interface Logger {
public void log(String msg);
}
一般我们会把日志保存中文件中,所以有了一个FileLogger
public class FileLogger implements Logger {
public void log(String msg) {
//开始记录日志到文件中
}
}
此时如果在项目有些地方需要对日志进行加密,有些地方又不需要加密,或者有些地方生成的文件是以xml的方式。此时如果采用继承的方法,也能实现,但是从面向对象的角度来说,并不建议对象的层次太深,增加系统的复杂性,这样对于系统的扩展和维护都不是很方便。此时Decorator模式就可以帮我们解决这些问题,我们可以为这个一般的FileLogger对象上刷一层不同的漆,那么这些漆,从上面增加的功能角度来说,就是加了一个“加密”的漆,或加了一层“生成xml”的漆。
先定义一个Decorator接口,此接口也实现了Logger接口
public class LoggerDecorator implements Logger{
Logger logger;
public LoggerDecorator(Logger logger){
this.logger=logger;
}
//开始记录日志
public void log(String msg){
//此处便是给实现了Logger接口的,被刷了油漆的(增加了功能的例如加密等)对象记录日志
logger.log(msg);
}
}
public class EncryptDecorator extends LoggerDecorator{
public EncryptDecorator(Logger logger){
super(logger);
}
public void log(String msg){
//刷加密字符串的油漆
msg=this.encryptMsg(msg);
//记录加密后的日志
logger.log(msg);
}
}
//客户端的调用
public DecoratorClient{
public static void main(String args[]){
Logger logger=new FileLogger();
Logger decorator=new EncryptDecorator(logger);
decorator.log("加密的字符串");
}
}
这样就基本把Decorator模式的应用起来,当然在项目中我们可能还需要更丰富一下我们的类,此处仅用这样的简单示例来讲述。