第一講是裝飾器。當(dāng)初我在學(xué)裝飾器模式的時(shí)候總是感覺似懂非懂,一直沒有真正理解。其實(shí)裝飾器也叫油漆工模式,再加上在我們的java類庫(kù)中有很多是實(shí)現(xiàn)了裝飾器模式的類。比方說(shuō):在讀取文件時(shí)
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
這其實(shí)就是一個(gè)decorator模式。因?yàn)獒槍?duì)File的讀取方式有很多,如果每種都要采用繼承的方法,那么會(huì)產(chǎn)生很多的子類,那樣顯然是很煩的。
裝飾器也稱為油漆工模式。它的目的就是給一個(gè)對(duì)象動(dòng)態(tài)地添加一些功能。就像是給對(duì)象刷了一層漆,使這個(gè)對(duì)象更加豐富,而不是通過(guò)繼承來(lái)增加功能。而這些功能的添加是動(dòng)態(tài)的運(yùn)行期的,當(dāng)然這里的動(dòng)態(tài)并不是像aop中的引介introductor,大家不要混淆。
在我們的項(xiàng)目中,經(jīng)常會(huì)遇到日志的情況。大凡我們會(huì)定義一個(gè)log接口就像下面。
public interface Logger {
public void log(String msg);
}
一般我們會(huì)把日志保存中文件中,所以有了一個(gè)FileLogger
public class FileLogger implements Logger {
public void log(String msg) {
//開始記錄日志到文件中
}
}
此時(shí)如果在項(xiàng)目有些地方需要對(duì)日志進(jìn)行加密,有些地方又不需要加密,或者有些地方生成的文件是以xml的方式。此時(shí)如果采用繼承的方法,也能實(shí)現(xiàn),但是從面向?qū)ο蟮慕嵌葋?lái)說(shuō),并不建議對(duì)象的層次太深,增加系統(tǒng)的復(fù)雜性,這樣對(duì)于系統(tǒng)的擴(kuò)展和維護(hù)都不是很方便。此時(shí)Decorator模式就可以幫我們解決這些問(wèn)題,我們可以為這個(gè)一般的FileLogger對(duì)象上刷一層不同的漆,那么這些漆,從上面增加的功能角度來(lái)說(shuō),就是加了一個(gè)“加密”的漆,或加了一層“生成xml”的漆。
先定義一個(gè)Decorator接口,此接口也實(shí)現(xiàn)了Logger接口
public class LoggerDecorator implements Logger{
Logger logger;
public LoggerDecorator(Logger logger){
this.logger=logger;
}
//開始記錄日志
public void log(String msg){
//此處便是給實(shí)現(xiàn)了Logger接口的,被刷了油漆的(增加了功能的例如加密等)對(duì)象記錄日志
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);
}
}
//客戶端的調(diào)用
public DecoratorClient{
public static void main(String args[]){
Logger logger=new FileLogger();
Logger decorator=new EncryptDecorator(logger);
decorator.log("加密的字符串");
}
}
這樣就基本把Decorator模式的應(yīng)用起來(lái),當(dāng)然在項(xiàng)目中我們可能還需要更豐富一下我們的類,此處僅用這樣的簡(jiǎn)單示例來(lái)講述。