類別:責任鏈設計模式
目的:解耦行為的接收方和行為的實際處理邏輯
完整程式碼參考:1drv.ms/u/s!AquRvPz…
典型場景
gui視窗介面上的一個按鈕物件,點選後執行一斷邏輯處理程式碼
硬編碼
構造一個按鈕類,並在點選(click)時執行業務邏輯程式碼,參考程式碼如下:
public class Button {
private String label;
public void click() {
// doBusinessLogic(); 邏輯處理程式碼
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
複製程式碼
核心問題
按鈕和按鈕點後的業務邏輯程式碼耦合在一起
- button的複用變得困難
- 邏輯程式碼的複用變得困難
解決方式:命令模式,將業務邏輯程式碼和按鈕分開,使得button和邏輯程式碼都變得比較容易複用
模式實現
將邏輯程式碼單獨進行封裝,這部分封裝就是命令模式中的命令
單獨封裝業務邏輯
public interface Command {
void execute();
}
public class BusinessLogicCommand implements Command {
@Override
public void execute() {
System.out.println("business logic here...");
}
}
複製程式碼
按鈕中持有對業務邏輯的引用
public class Button {
private String label;
private Command command;
public Button(Command command) {
this.command = command;
}
public void click() {
command.execute();
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
複製程式碼
使用方式
var command = new BusinessLogicCommand();
var button = new Button(command);
button.click();
複製程式碼
可以看到命令使用了介面、可以方便的進行業務邏輯的擴充套件
一些注意的點
命令模式中的Command物件特性
- 可被持久化、比如從關鍵狀態中恢復以前的狀態
- 可被撤銷、比如執行刪除命令時,先儲存被刪除的內容,可在需要時恢復被刪除的內容
java 持久化參考程式碼如下(stat為需要持久化的物件)
// 持久化物件到檔案
var fileStream = new FileOutputStream("stat.txt");
var objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(stat);
objectStream.close();
// 從檔案恢復物件
var fileStream = new FileInputStream("history.txt");
var objectStream = new ObjectInputStream(fileStream);
var stat = (Stat) objectStream.readObject();
複製程式碼
為什麼命令模式更好
- 避免大量的耦合
- 減少基礎元件的重複、比如介面上許多的按鈕,大部分可以重用