對裝飾器模式的理解
我們為什麼使用裝飾器模式?
使用裝飾器模式能在不改變原始碼的基礎上,對原始碼的功能進行拓展,即為一個類新增一些功能,同時又不希望改變這個類原來的結構。我舉以下例子進行說明。
例如:我已經完成了一個日誌的介面和它的各個實現類,但是這些類只有輸出日誌到不同地方的功能,LoggerFileSystem能將日誌輸出到檔案系統(磁碟)中,LoggerCloud能將日誌輸出到雲端的某個檔案中。現在新需求來了,假如我想要在每條日誌輸出後順帶輸出這條日誌的時間,我們把它假設為功能一(functionOne);假如我還想再此基礎上輸出日誌內容,我們把它假設為功能二(functionTwo)。我們為日誌添加了功能而我們不想去修改每個實現類的方法,這時候就能使用裝飾者模式,為這個介面編寫一個裝飾類,修飾原來的日誌輸出。
log()定義日誌輸出的方法
/**
* Created by AQ on 2018/7/11.
*/
public interface Logger {
public void log();
}
LoggerCloud和LoggerFileSystem為原有的結構(我們未對日誌功能進行拓展時已存在)
/** * Created by AQ on 2018/7/11. */ public class LoggerCloud implements Logger { @Override public void log() { System.out.println("Log in Cloud"); } }
/**
* Created by AQ on 2018/7/11.
*/
public class LoggerFileSystem implements Logger {
@Override
public void log() {
System.out.println("Log in FileSystem");
}
}
為Logger編寫一個裝飾器,拓展log()的功能,這個裝飾類要實現Logger介面並且擁有一個Logger成員
/** * Created by AQ on 2018/7/11. */ public class Decorator implements Logger { protected Logger logger; Decorator(Logger logger){ this.logger=logger; } @Override public void log() { if(logger!=null){ logger.log(); } } }
FunctionOne和FunctionTwo的newFunction()即我們想要新增的功能
/**
* Created by AQ on 2018/7/11.
*/
public class FunctionTwo extends Decorator {
FunctionTwo(Logger logger) {
super(logger);
}
@Override
public void log() {
super.log();
functionTwo();
}
public void functionTwo(){
System.out.println("new function two");
}
}
/**
* Created by AQ on 2018/7/11.
*/
public class FunctionOne extends Decorator {
FunctionOne(Logger logger) {
super(logger);
}
public void newFunction(){
System.out.println("new function one");
}
@Override
public void log() {
super.log();
newFunction();
}
}
main方法
public class Main {
public static void main(String[] args) {
Logger logger = new LoggerCloud();
logger.log();
System.out.println();
Logger logger1 = new FunctionOne(logger);
logger1.log();
System.out.println();
Logger logger2 = new FunctionTwo(logger1);
logger2.log();
}
}
輸出結果為
Log in Cloud
Log in Cloud
new function one
Log in Cloud
new function one
new function two
結果分析
logger.log()呼叫的是LoggerCloud類中log()方法,輸出 Log in Cloud
logger1.log()呼叫的是FunctionOne類中的log()方法,先執行super.log(),即FunctionOne的父類Decorator的log()方法,由於在構造logger1時傳入的值是logger,所以此時Decorator的log()方法執行的是logger.log(),輸出Log in Cloud。然後執行到logger1.log()中的newFunction(),輸出new function one。
logger2.log()呼叫的是FunctionTwo類中的log()方法,先執行super.log(),即FunctionTwo的父類Decorator的log()方法,由於在構造logger2時傳入的值是logger1,所以此時Decorator的log()方法執行的是logger1.log(),
輸出 Log in Cloud
new function one
然後執行到logger2.log()中的newFunction(),
輸出new function two。
本文參考了https://blog.csdn.net/qq_24448899/article/details/78068813