行為模式:關註系統中對象之間的相互交互,研究運行時對象之間的相互通信和協作,明確對象職責 1.模板方法模式(template method) 定義了一個操作中的演算法骨架,將某些步驟延遲到子類中實現。這樣,新的子類可以在不改變一個演算法結構的前提下重新定義該演算法的某些特定步驟。 即:處理步驟父類中定義好 ...
行為模式:關註系統中對象之間的相互交互,研究運行時對象之間的相互通信和協作,明確對象職責
1.模板方法模式(template method)
定義了一個操作中的演算法骨架,將某些步驟延遲到子類中實現。這樣,新的子類可以在不改變一個演算法結構的前提下重新定義該演算法的某些特定步驟。
即:處理步驟父類中定義好,具體實現延遲到子類中定義。
開發中:資料庫訪問的封裝、Junit單元測試、servlet中doGet/doPost方法調用、Hibernate中模板程式等等
銀行案例:
1 public abstract class BankTemplateMethod { 2 3 //具體方法 4 public void takeNumber() { 5 System.out.println("取號排隊"); 6 } 7 8 //辦理具體業務 、鉤子方法 9 public abstract void transact(); 10 public void evaluate() { 11 System.out.println("反饋評分"); 12 } 13 14 //模板方法 15 public final void process() { 16 this.takeNumber(); 17 18 this.transact(); 19 20 this.evaluate(); 21 } 22 23 }銀行模板
1 public class Client { 2 public static void main(String[] args) { 3 // BankTemplateMethod btm = new DrawMoney(); 4 // btm.process(); 5 6 //採用匿名內部類 7 BankTemplateMethod btm2 = new BankTemplateMethod() { 8 9 @Override 10 public void transact() { 11 System.out.println("我要存錢"); 12 } 13 }; 14 btm2.process(); 15 16 } 17 } 18 19 20 21 class DrawMoney extends BankTemplateMethod{ 22 @Override 23 public void transact() { 24 System.out.println("我要取款"); 25 } 26 }測試
2.命令模式(command)
- 抽象命令類Command
- 具體命令類ConcreteCommand
- 調用者/請求者Invoker:請求的發送者,通過命令對象來執行請求。調用者只與抽象命令類存在關聯,運行時調用命令對象的execcute(),間接調用接收者的相關操作。
- 接收者Receiver:1、接收者執行與請求相關的操作,具體實現對請求業務的處理。2、未抽象前,實際執行操作內容的對象
- 客戶類Client:需要創建調用者和具體命令類對象,在創建具體命令對象時指定對應的接收者。發送者和接收者沒有直接關係,都通過命令對象間接調用
應用於:Struts2中action調用、資料庫事務機制、命令的撤銷和恢復。
1 public interface Command { 2 void execute(); 3 }抽象命令類
1 public class ConcreteCommand implements Command{ 2 private Receiver receiver;//命令的真正執行者 3 4 public ConcreteCommand(Receiver receiver) { 5 super(); 6 this.receiver = receiver; 7 } 8 9 @Override 10 public void execute() { 11 //命令執行前後,可執行相關處理 12 receiver.action(); 13 } 14 15 }具體命令類
1 public class Receiver { 2 public void action() { 3 System.out.println("出發!"); 4 } 5 }真正命令的執行者、接收者
1 public class Invoke { 2 private Command command;/*也可以通過容器List<Command> 3 容納很多命令對象,進行批處理。資料庫底層的事務管理就是類似的結構!*/ 4 5 public Invoke(Command command) { 6 super(); 7 this.command = command; 8 } 9 10 //業務方法,用於調用命令類方法 11 public void call() { 12 command.execute(); 13 } 14 15 }調用者、發起者
1 public class Client { 2 public static void main(String[] args) { 3 Command c = new ConcreteCommand(new Receiver()); 4 Invoke i = new Invoke(c); 5 6 i.call(); 7 8 } 9 }客戶類
3.迭代器模式(iterator)
- JDK內置迭代器(List/Set)
4.觀察者模式(Observer)
主要用於1:N的通知。當一個對象的狀態變化時,他需要及時告知一系列對象,令他們做出響應
- 推:每次 都會把通知以廣播方式發送給所有觀察者 ,所有觀察者只能被動接收。
- 拉:觀察者只要知道有情況即可。至於什麼時候獲取內容,獲取什麼內容都可以自主決定
開發中:聊天室,伺服器發個所有客戶端、網路游戲、郵件訂閱、Servlet中,監聽器、Android中,廣播機制、商城中,群發消息。
5.中介者模式(Mediator)
本質是解耦多個同事對象之間的交互關係。每個對象都持有中介者對象的引用,只跟中介者對象打交道,通過中介者統一管理這些交互關係
應用:
MVC模式、視窗游戲程式、圖形界面開發GUI
公司部門案例:
1 public interface Mediator { 2 void register(String dname,Department d); 3 void command(String dname); 4 }中介者介面
1 public interface Department { 2 void selfAction();//做本職工作 3 void outAction();//向上級彙報工作 4 }同事類(部門類)介面
1 public class Market implements Department{ 2 3 private Mediator m;//持有中介者的引用 4 5 public Market(Mediator m) { 6 super(); 7 this.m = m; 8 m.register("market",this); 9 } 10 11 @Override 12 public void selfAction() { 13 System.out.println("彙報工作,項目進度需要資金"); 14 15 m.command("finacial"); 16 } 17 18 @Override 19 public void outAction() { 20 System.out.println("開發市場"); 21 } 22 23 }市場部門
1 public class Finacial implements Department{ 2 3 private Mediator m;//持有中介者的引用 4 5 public Finacial(Mediator m) { 6 super(); 7 this.m = m; 8 m.register("finacial",this); 9 } 10 11 @Override 12 public void selfAction() { 13 System.out.println("彙報工作,資金充裕"); 14 15 } 16 17 @Override 18 public void outAction() { 19 System.out.println("整理資金"); 20 } 21 22 }財務部門
1 public class President implements Mediator{ 2 3 private Map<String,Department> map = new HashMap<String,Department>(); 4 5 @Override 6 public void register(String dname, Department d) { 7 map.put(dname, d); 8 } 9 10 @Override 11 public void command(String dname) { 12 map.get(dname).selfAction(); 13 } 14 }總經理
1 public class Client { 2 public static void main(String[] args) { 3 Mediator m = new President(); 4 5 Market market = new Market(m); 6 Finacial f = new Finacial(m); 7 8 market.selfAction(); 9 market.outAction(); 10 } 11 }測試
6.備忘錄模式(memento)
保存某個對象內部狀態的拷貝,以後可以將該對象恢復到原先狀態
結構:
- 源發器類Originator
- 備忘錄類Memento
- 負責人類CareTake
開發中:棋類游戲,悔棋、普通軟體的撤銷操作、資料庫軟體中的回滾操作、歷史記錄
1 public class Emp { 2 private String ename; 3 private int age; 4 5 //進行備忘操作,並返回備忘錄對象 6 public EmpMemento memento() { 7 return new EmpMemento(this); 8 } 9 10 //進行數據恢復,恢覆成制定備忘錄對象的值 11 public void recovery(EmpMemento mmt) { 12 this.ename = mmt.getEname(); 13 this.age = mmt.getAge(); 14 } 15 16 public Emp(String ename, int age) { 17 super(); 18 this.ename = ename; 19 this.age = age; 20 } 21 22 public String getEname() { 23 return ename; 24 } 25 26 public void setEname(String ename) { 27 this.ename = ename; 28 } 29 30 public int getAge() { 31 return age; 32 } 33 34 public void setAge(int age) { 35 this.age = age; 36 } 37 38 }源發器類
1 public class EmpMemento { 2 private String ename; 3 private int age; 4 5 public EmpMemento(Emp e) { 6 this.ename = e.getEname(); 7 this.age = e.getAge(); 8 9 } 10 11 public String getEname() { 12 return ename; 13 } 14 15 public void setEname(String ename) { 16 this.ename = ename; 17 } 18 19 public int getAge() { 20 return age; 21 } 22 23 public void setAge(int age) { 24 this.age = age; 25 } 26 27 }備忘錄類
1 public class CareTaker { 2 private EmpMemento memento; 3 4 public EmpMemento getMemento() { 5 return memento; 6 } 7 8 public void setMemento(EmpMemento memento) { 9 this.memento = memento; 10 } 11 12 13 }負責人類,管理備忘錄對象
1 public class Client { 2 public static void main(String[] args) { 3 CareTaker taker = new CareTaker(); 4 5 Emp emp = new Emp("張三",18); 6 System.out.println("第一次列印:"+emp.getEname()+"---"+emp.getAge()); 7 8 taker.setMemento(emp.memento());//備忘一次 9 10 emp.setAge(28); 11 emp.setEname("李四"); 12 13 System.out.println("第二次列印:"+emp.getEname()+"---"+emp.getAge()); 14 15 //恢復到備忘存儲的對象 16 emp.recovery(taker.getMemento()); 17 System.out.println("第三次列印:"+emp.getEname()+"---"+emp.getAge()); 18 } 19 }測試
7.解釋器模式(Interpreter)
開發常見:EL表達式、正則表達式、SQL語法、數學表達式
基本用不著
8.狀態模式(state)
用於解決系統中複雜對象的狀態轉換以及不同狀態下行為的封裝問題
結構:
- 環境類Context:環境類中維護一個State對象,他是定義了當前的狀態。
- 抽象狀態類State
- 具體狀態類ConcreteState:每一個類封裝了一個狀態對應的行為
開發中:銀行系統中賬號狀態管理、OA系統公文狀態管理、酒店系統房間狀態管理、線程對象各狀態之間的切換
酒店管理案例:
1 public interface State { 2 void handle(); 3 }抽象類/抽象狀態類
1 public class FreeState implements State{ 2 @Override 3 public void handle() { 4 System.out.println("房間空閑"); 5 } 6 }酒店房間-空閑狀態/具體狀態類
1 public class CheckedInState implements State{ 2 @Override 3 public void handle() { 4 System.out.println("房間已入住"); 5 } 6 }酒店房間--已入住/具體狀態類
1 public class BookedState implements State{ 2 @Override 3 public void handle() { 4 System.out.println("房間已預訂"); 5 } 6 }酒店房間---已預訂/具體狀態類
1 public class Context { 2 private State state; 3 4 //重點! 5 public void setState(State s) { 6 System.out.println("切換狀態"); 7 state = s; 8 state.handle(); 9 } 10 11 }房間對象/環境類
1 public class Client { 2 public static void main(String[] args) { 3 Context c = new Context(); 4 5 c.setState(new FreeState()); 6 c.setState(new CheckedInState()); 7 c.setState(new BookedState()); 8 } 9 }測試
9.策略模式(Strategy)
對應於解決某個問題的一個演算法族,允許用戶從該演算法族中任選一個演算法解決某一問題,同時可以方便的更換演算法或新增演算法。並且由客戶端決定調用哪個演算法。
開發中:GUI中佈局管理、Spring框架中,Resource介面、資源訪問策略
會員案例:
1 public interface Strategy { 2 public double getPrice(double standardPrice); 3 }介面類
1 public class New implements Strategy{ 2 @Override 3 public double getPrice(double standardPrice) { 4 System.out.println("不打折,原價"); 5 return standardPrice; 6 } 7 }新客戶
1 public class Old implements Strategy{ 2 @Override 3 public double getPrice(double standardPrice) { 4 System.out.println("打八折"); 5 return standardPrice*0.8; 6 } 7 }老客戶
1 public class Context { 2 private Strategy strategy;//當前採用的演算法對象 3 4 //可以通過構造器來註入 5 public Context(Strategy strategy) { 6 super(); 7 this.strategy = strategy; 8 } 9 10 //可以通過set方法註入 11 public void setStrategy(Strategy strategy) { 12 this.strategy = strategy; 13 } 14 15 //自身方法 16 public void pringPrice(double s) { 17 System.out.println("報價:"+strategy.getPrice(s)); 18 } 19 }交互類(和具體的策略類交互)
1 public class Cilent { 2 public static void main(String[] args) { 3 4 Strategy s1 = new Old(); 5 Context ctx = new Contex