23種設計模式-----行為模式

来源:https://www.cnblogs.com/lhl0131/archive/2020/02/27/12369465.html
-Advertisement-
Play Games

行為模式:關註系統中對象之間的相互交互,研究運行時對象之間的相互通信和協作,明確對象職責 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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Java 多線程同步 synchronized 多線程的同步問題指的是多個線程同時修改一個數據的時候,可能導致的問題 多線程的問題,又叫 Concurrency 問題 步驟 1 : 演示同步問題 假設蓋倫有10000滴血,並且在基地里,同時又被對方多個英雄攻擊 就是有 多個線程在減少蓋倫的hp 同時 ...
  • 1 matlab概貌 MATLAB是MATrix LABoratory(矩陣實驗室)的縮寫,是一款由美國The MathWorks公司出品的商業數學軟體。matlab是一種用於演算法開發、數據可視化、數據分析以及數值計算的高級技術計算語言和互動式環境。除了矩陣運算、繪製函數/數據圖像等常用功能外,ma ...
  • 問題描述 輸入兩個整數a和b,輸出這兩個整數的和。a和b都不超過100位。 演算法描述 由於a和b都比較大,所以不能直接使用語言中的標準數據類型來存儲。對於這種問題,一般使用數組來處理。定義一個數組A,A[0]用於存儲a的個位,A[1]用於存儲a的十位,依此類推。同樣可以用一個數組B來存儲b。計算c  ...
  • 1、格式 [數據1,數據2,數據3,...] 列表可以一次性存多個數據,可以為不同的數據類型 2、下標 從0開始循序向下分配 3、常用函數 查找 index():返回指定數據所在位置下標,不存在就報錯 count():返回某個字串在字元串中出現的次數 len():返回列表列表中的數據個數 name= ...
  • 4.單例模式詳解 4.1.課程目標 1、掌握單例模式的應用場景。 2、掌握IDEA環境下的多線程調試方式。 3、掌握保證線程安全的單例模式策略。 4、掌握反射暴力攻擊單例解決方案及原理分析。 5、序列化破壞單例的原理及解決方案。 6、掌握常見的單例模式寫法。 4.2.內容定位 1、聽說過單例模式,但 ...
  • 1、條件語句 if if…else… 多重if if嵌套 三目運算符 (化簡的if else) if 條件: 條件成立執行代碼1 條件成立執行代碼2 if False: print('if判斷為假,不執行') print('有減進的語句都在if里') print('沒有縮進,我不是if,可以執行') ...
  • c語言心形告白代碼實現 1.彩色告白 include include include include define U 0.1 define V 0.053 void SetColor(unsigned short ForeColor,unsigned short BackGroundColor) ...
  • go 語言中文網(每日資訊)_2020 02 27 一、Go 語言中文網 1. "如何正確看待 Google 宣佈 Fuchsia 操作系統沒有選 Go 作為終端開發語言 " 2. "Actor 還是 CSP?Go 中的併發模式還能講這麼細緻" 3. "【每日一庫】讓你的 json 可以 grep: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...