1. 程式人生 > >研磨設計模式 之 備忘錄模式(Memento)1——跟著cc學設計系列

研磨設計模式 之 備忘錄模式(Memento)1——跟著cc學設計系列

19.1  場景問題

19.1.1  開發模擬系統

考慮這樣一個模擬應用,功能是:模擬運行鍼對某個具體問題的多個解決方案,記錄執行過程的各種資料,在模擬執行完成過後,好對這多個解決方案進行比較和評價,從而選定最優的解決方案。

這種模擬系統,在很多領域都有應用,比如:工作流系統,對同一問題制定多個流程,然後通過模擬執行,最後來確定最優的流程做為解決方案;在工業設計和製造領域,模擬系統的應用就更廣泛了。

由於都是解決同一個具體的問題,這多個解決方案並不是完全不一樣的,假定它們的前半部分執行是完全一樣的,只是在後半部分採用了不同的解決方案,後半部分需要使用前半部分執行所產生的資料。

由於要模擬執行多個解決方案,而且最後要根據執行結果來進行評價,這就意味著每個方案的後半部分的初始資料應該是一樣,也就是說在執行每個方案後半部分之前,要保證資料都是由前半部分執行所產生的資料,當然,咱們這裡並不具體的去深入到底有哪些解決方案,也不去深入到底有哪些狀態資料,這裡只是示意一下。

那麼,這樣的系統該如何實現呢?尤其是每個方案執行需要的初始資料應該一樣,要如何來保證呢?

19.1.2  不用模式的解決方案

       要保證初始資料的一致,實現思路也很簡單:

  • 首先模擬執行流程第一個階段,得到後階段各個方案執行需要的資料,並把資料儲存下來,以備後用
  • 每次在模擬執行某一個方案之前,用儲存的資料去重新設定模擬執行流程的物件,這樣執行後面不同的方案時,對於這些方案,初始資料就是一樣的了

根據上面的思路,來寫出模擬執行的示意程式碼,示例程式碼如下:

/**

 * 模擬執行流程A,只是一個示意,代指某個具體流程

 */

public class FlowAMock {

    /**

     * 流程名稱,不需要外部儲存的狀態資料

     */

    private String flowName;

    /**

     * 示意,代指某個中間結果,需要外部儲存的狀態資料

     */

    private int tempResult;

    /**

     * 示意,代指某個中間結果,需要外部儲存的狀態資料

     */

    private String tempState;

    /**

     * 構造方法,傳入流程名稱

     * @param flowName 流程名稱

     */

    public FlowAMock(String flowName){

       this.flowName = flowName;

    }

    public String getTempState() {

       return tempState;

    }

    public void setTempState(String tempState) {

       this.tempState = tempState;

    }

    public int getTempResult() {

       return tempResult;

    }

    public void setTempResult(int tempResult) {

       this.tempResult = tempResult;

    }

    /**

     * 示意,執行流程的第一個階段

     */

    public void runPhaseOne(){

       //在這個階段,可能產生了中間結果,示意一下

       tempResult = 3;

       tempState = "PhaseOne";

    }

    /**

     * 示意,按照方案一來執行流程後半部分

     */

    public void schema1(){

       //示意,需要使用第一個階段產生的資料

       this.tempState += ",Schema1";

       System.out.println(this.tempState

+ " : now run "+tempResult);

       this.tempResult += 11;

    }

    /**

     * 示意,按照方案二來執行流程後半部分

     */

    public void schema2(){

       //示意,需要使用第一個階段產生的資料

       this.tempState += ",Schema2";

       System.out.println(this.tempState

+ " : now run "+tempResult);

       this.tempResult += 22;

    }  

}

(2)看看如何使用這個模擬流程的物件,寫個客戶端來測試一下。示例程式碼如下:

public class Client {

    public static void main(String[] args) {

       // 建立模擬執行流程的物件

       FlowAMock mock = new FlowAMock("TestFlow");

       //執行流程的第一個階段

       mock.runPhaseOne();

       //得到第一個階段執行所產生的資料,後面要用

       int tempResult = mock.getTempResult();

       String tempState = mock.getTempState();

       //按照方案一來執行流程後半部分

       mock.schema1();

       //把第一個階段執行所產生的資料重新設定回去

       mock.setTempResult(tempResult);

       mock.setTempState(tempState);

       //按照方案二來執行流程後半部分

       mock.schema2();

    }

}

執行結果如下:

PhaseOne,Schema1 : now run 3

PhaseOne,Schema2 : now run 3

       仔細看,上面結果中框住的部分,是一樣的值,這說明執行時,它們的初始資料是一樣的,基本滿足了功能要求。

19.1.3  有何問題

看起來實現很簡單,是吧,想一想有沒有什麼問題呢?

上面的實現有一個不太好的地方,那就是資料是一個一個零散著在外部存放的,如果需要外部存放的資料多了,會顯得很雜亂。這個好解決,只需要定義一個數據物件來封裝這些需要外部存放的資料就可以了,上面那樣做是故意的,好提醒大家這個問題。這個就不去示例了。

還有一個嚴重的問題,那就是:為了把執行期間的資料放到外部儲存起來,模擬流程的物件被迫把內部資料結構開放出來,這暴露了物件的實現細節,而且也破壞了物件的封裝性。本來這些資料只是模擬流程的物件內部資料,應該是不對外的。

那麼究竟如何實現這樣的功能會比較好呢?


---------------------------------------------------------------------------

研磨設計討論群【252780326】

---------------------------------------------------------------------------

相關推薦

研磨設計模式 備忘錄模式Memento1——跟著cc設計系列

19.1  場景問題 19.1.1  開發模擬系統 考慮這樣一個模擬應用,功能是:模擬運行鍼對某個具體問題的多個解決方案,記錄執行過程的各種資料,在模擬執行完成過後,好對這多個解決方案進行比較和評價,從而選定最優的解決方案。 這種模擬系統,在很多領域都有應用,比如:工作流系

研磨設計模式 原型模式Prototype1 ——跟著cc設計系列

9.1  場景問題 9.1.1  訂單處理系統 考慮這樣一個實際應用:訂單處理系統。 現在有一個訂單處理的系統,裡面有個儲存訂單的業務功能,在這個業務功能裡面,客戶有這麼一個需求:每當訂單的預定產品數量超過1000的時候,就需要把訂單拆成兩份訂單來儲存,如果拆成兩份訂單

研磨設計模式 迭代器模式Iterator1——跟著cc設計系列

14.1  場景問題 14.1.1  工資表資料的整合        考慮這樣一個實際應用:整合工資表資料。        這個專案的背景是這樣的,專案的客戶方收購了一家小公司,這家小公司有自己的工資系統,現在需要整合到客戶方已有的工資系統上。        客戶方已有的工

研磨設計模式 代理模式Proxy1——跟著cc設計系列

11.1  場景問題 11.1.1  訪問多條資料        考慮這樣一個實際應用:要一次性訪問多條資料。        這個功能的背景是這樣的;在一個HR(人力資源)應用專案中客戶提出,當選擇一個部門或是分公司的時候,要把這個部門或者分公司下的所有員工都顯示出來,而且

研磨設計模式 代理模式Proxy2——跟著cc設計系列

11.2  解決方案 11.2.1  代理模式來解決 用來解決上述問題的一個合理的解決方案就是代理模式。那麼什麼是代理模式呢? (1)代理模式定義   (2)應用代理模式來解決的思路 仔細分析上面的問題,一次性訪問多條資料,這個可能性是很難避免的,是客戶的需要。也就是說,

研磨設計模式 原型模式Prototype2 ——跟著cc設計系列

9.2  解決方案 9.2.1  原型模式來解決 用來解決上述問題的一個合理的解決方案就是原型模式。那麼什麼是原型模式呢? (1 )原型模式定義   (2 )應用原型模式來解決的思路 仔細分析上面的問題,在saveOrder方法裡面,已經有了訂單介面型別的物件例項,是從外部傳入的,但是這裡只是知道這

研磨設計模式 迭代器模式Iterator2——跟著cc設計系列

14.2  解決方案 14.2.1  迭代器模式來解決 用來解決上述問題的一個合理的解決方案就是迭代器模式。那麼什麼是迭代器模式呢? (1)迭代器模式定義   所謂聚合是:指一組物件的組合結構,比如:Java中的集合、陣列等。 (2)應用迭代器模式來解決的思路      

研磨設計模式 直譯器模式Interpreter2——跟著cc設計系列

21.2  解決方案 21.2.1  直譯器模式來解決 用來解決上述問題的一個合理的解決方案,就是使用直譯器模式。那麼什麼是直譯器模式呢? (1)直譯器模式定義          這裡的文法,簡單點說就是我們俗稱的“語法規則”。 (2)應用直譯器模式來解決的思

研磨設計模式 代理模式Proxy3——跟著cc設計系列

11.3  模式講解 11.3.1  認識代理模式 (1)代理模式的功能 代理模式是通過建立一個代理物件,用這個代理物件去代表真實的物件,客戶端得到這個代理物件過後,對客戶端沒有什麼影響,就跟得到了真實物件一樣來使用。        當客戶端操作這個代理物件的時候,實際上功

淺談JAVA設計模式——備忘錄模式Memento

一、概述 在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。 二、適用性 1.必須儲存一個物件在某一個時刻的(部分)狀態,這樣以後需要時它才能恢復到先前的狀態。 2.如果一個用介面來讓其它物件直接得到這

面向物件設計模式---備忘錄模式(Memento Pattern)

今天要向大家介紹的模式是備忘錄模式,有時又稱作快照模式。 這個備忘錄模式一個典型的應用場景就是遊戲存檔。有時候為了打Boss,沒有成功,反而被Boss打死了,這個時候就需要利用我們之前的存檔回到最接近Boss的那一關再繼續。 備忘錄模式的定義如下: 在不破壞封裝性的前

設計模式問題集錦

是把 後繼 ogr data- 跟著 沒有 解釋器 space 基本實現 設計模式的主要資料是《大話設計模式》。第一階段先看看各種模式的基本概念。實現每一個模式下的樣例。然後在進行理解性的學習和掌握,靈活掌握各種模式的長處,知道某種模式適合那種狀態。如今,樣

設計模式備忘錄模式

set 2017年 image 對象 array mem .com void oid 代碼實現 /** * 源發器類 * @author bzhx * 2017年3月15日 */ public class Emp { private

設計模式六大原則轉載

具體類 ima 傳遞參數 基礎上 比較 擁有 tex 至少 基類 關於設計模式的六大設計原則的資料網上很多,但是很多地方解釋地都太過於籠統化,我也找了很多資料來看,發現CSDN上有幾篇關於設計模式的六大原則講述的比較通俗易懂,因此轉載過來。   原作者博客鏈接:http:/

Java 設計模式 備忘錄模式

clas AR java OS ont pre pub HR http http://www.verejava.com/?id=16999143457673 package com.memento.theory; import java.util.Stack; publ

設計模式的藝術 行為型模式備忘錄模式

前言 每個人都會有後悔的時候,可是人生沒有後悔藥,做過的事情無法再去後悔,軟體設計中卻是有這麼一種後悔機制,叫做備忘錄模式,它就是軟體中的"後悔藥" 什麼是備忘錄模式  Memento Pattern 在不破壞封裝的前提下,捕獲一個物件的內部狀態,並在物件之外儲存這個狀態,這樣

設計模式的藝術 行為型模式備忘錄模式

前言 每個人都會有後悔的時候,可是人生沒有後悔藥,做過的事情無法再去後悔,軟體設計中卻是有這麼一種後悔機制,叫做備忘錄模式,它就是軟體中的"後悔藥" 什麼是備忘錄模式  Memento Pattern 在不破壞封裝的前提下,捕獲一個物件的內部狀態,並在物件之外儲存這個狀

Java設計模式總體簡介——簡單易懂

設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。 毫無疑問,設計模式於己於他人於系統都是多贏的,設計模式使程式碼編制真正工程化,設計模式是

設計模式裝飾者Decorator模式

首先來看一個場景,如圖: 工人分為很多種類,比如電工,管道工等等,同時又有A公司的電工,B公司的電工,A公司的管道工,B公司的管道工等等,那麼當有M個工種和N個公司的時候,就會有 M * N 個子類,這個繼承體系就會變得很龐大和複雜。那麼如何簡化呢,那麼

c++的設計模式備忘錄模式

備忘錄模式就是能夠儲存當前狀態,類似於玩遊戲的時候可以不斷的讀檔,同時在玩了新的遊戲的時候,又可以更新到檔案裡。 #include <iostream> #include <vector> using namespace std; //需儲存的資