第一講是裝飾器。當初我在學裝飾器模式的時候總是感覺似懂非懂,一直沒有真正理解。其實裝飾器也叫油漆工模式,再加上在我們的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模式的應用起來,當然在項目中我們可能還需要更豐富一下我們的類,此處僅用這樣的簡單示例來講述。