/************************************************************************ * 策略模式學習筆記[C++] * Author: 陳相禮 * Time: 2009.12.02 * Compiler: VC8 ************************************************************************/ #include "StrategyPattern.h" #include "StrategyPattern1.h" #include <iostream> using namespace std; int main() { //------------------策略原理類測試------------------- Context *context; context = new Context( new ConcreteStrategyA() ); context->vContextInterface(); context = new Context( new ConcreteStrategyB() ); context->vContextInterface(); context = new Context( new ConcreteStrategyC() ); context->vContextInterface(); delete(context); //------------------策略類測試------------------- CashContext *cs; double dwMoney; cs = new CashContext( new CashNormal() ); dwMoney = cs->dwGetResult( 700 ); cs = new CashContext( new CashRebate( 0.8 ) ); dwMoney = cs->dwGetResult( 700 ); cs = new CashContext( new CashReturn( 300, 100 ) ); dwMoney = cs->dwGetResult( 700 ); delete(cs); //------------------簡單工廠+策略類測試------------------- CashContextF *csf; csf = new CashContextF( 'N' ); dwMoney = csf->dwGetResult( 700 ); csf = new CashContextF( 'R' ); dwMoney = csf->dwGetResult( 700 ); csf = new CashContextF( 'T' ); dwMoney = csf->dwGetResult( 700 ); delete(csf); return 0; } /************************************************************************ * 總結: * 1、策略模式是一種定義一系列算法的方法,從概念上看所有這些算法 * 完成的都是相同的工作,只是實現不同,它可以以相同的方式調用 * 所有算法,減少了各種算法類與算法類之間的耦合。 * 2、策略模式的Strategy類層次爲Context定義了一系列可供重用的算法 * 或行爲。繼承有助於吸取出這些算法中的公共功能。 * 3、策略模式的優點是簡化了單元測試,因爲每個算法都有自己的類, * 可以通過自己的接口單獨測試。 * 4、當不同的行爲堆砌在一個類中時,就很難避免使用條件語句來選擇 * 合適的行爲。將這些行爲瘋長在一個個獨立的Strategy類中,可以在 * 使用這些行爲的類中消除條件語句。 * 5、策略模式是用來封裝算法的,但在實踐中,它可以封裝幾乎任何類 * 型的規則,只要在分析過程中聽到需要在不同時間應用不同的業務 * 規則,就可以考慮使用策略模式處理這種變化的可能性。 * 6、基本的策略模式中,選擇所用具體實現職責由客戶端對象承擔,並 * 轉給策略模式的Context對象。 * 7、任何需求的變更都是需要成本的。 ************************************************************************/ /************************************************************************ * 類的設計:單一職責原則 * 1、就一個類而言,應該僅有一個引起它變化的原因。 * 2、如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個 * 職責的變化可能削弱或者抑制這個類完成其他職責的能力。這種耦 * 合會導致脆弱的設計,當變化發生時,設計會遭到意想不到的破壞。 * 3、軟件設計真正要做的許多內容,就是發現職責並把那些職責相互分離 * 4、如果你能想到多餘一個的動機去改變一個類,那麼這個類就具有多於 * 一個職責,就應該考慮類的職責分離。 ************************************************************************/ /************************************************************************ * 類的設計:開放-封閉原則 * 1、軟件實體(類、模塊、函數等)應該可以擴展,但是不可修改。 * 2、此原則保證對需求的改變卻可以保持相對穩定,從而使得系統可以 * 在第一個版本以後不斷推出新的版本。 * 3、無論模塊是多麼的“封閉”,都會存在一些無法對之封閉的變化。既然 * 不可能完全封閉,設計人員必須對於他設計的模塊應該對哪種變化封 * 閉作出選擇。他必須先猜測出最有可能發生的變化種類,然後構造抽 * 象來隔離那些變化。 * 4、在我們最初編寫代碼時,假設變化不會發生。當變化發生時,我們就 * 創建抽象來隔離以後發生的同類變化。 * 5、面對需求,對程序的改動是通過增加新代碼進行的,而不是更改現有 * 的代碼。 * 6、我們希望的是在開發工作展開不久就知道可能發生的變化。查明可能 * 發生的變化所等待的時間越長,要創建正確的抽象就越困難。 * 7、開放-封閉原則是面向對象設計的核心所在。遵循這個原則可以帶來 * 面向對象技術所聲稱的巨大好處,也就是可維護、可擴展、可複用、 * 靈活性好。開發人員應該僅對程序中呈現出頻繁變化的那些部分作出 * 抽象,然而,對於應用程序中的每個部分都刻意地進行抽象同樣不是 * 一個好主意。拒絕不成熟的抽象和抽象本身一樣重要。切記! ************************************************************************/ /************************************************************************ * 類的設計:依賴倒轉原則[誰也不依賴誰] * 1、(1) 高層模塊不應該依賴低層模塊。兩個都應該依賴抽象。 * (2) 抽象不應該依賴細節,細節應該依賴抽象。即針對接口編程,不 * 要對實現編程。 * 2、里氏代換原則[LSP]:一個軟件實體如果使用的是一個父類的話,那麼 * 一定適用於其子類,而且它察覺不出父類對象和子類對象的區別。也 * 就是說,在軟件裏面,把父類都替換成它的子類,程序的行爲無變化。 * 3、只有當子類可以替換掉父類,軟件單位的功能不受到影響時,父類才 * 能真正被複用,而子類也能夠在父類的基礎上增加新的行爲。 * 4、由於子類型的可替換性才使得使用父類型的模塊在無需修改的情況下 * 就可以擴展。 * 5、依賴倒轉其實可以說是面向對象設計的標誌,用哪種語言來編寫程序 * 不重要,如果編寫時考慮的都是如何針對抽象編程而不是針對細節編 * 程,即程序中所有的依賴關係都是終止於抽象類或者接口,那就是面 * 向對象的設計,反之那就是過程化的設計了。 ************************************************************************/
#pragma once /********************************************** * 策略模式原理: * 定義算法家族,分別封裝起來,讓它們 * 之間可以相互替換,此模式讓算法的變 * 化,不會影響到使用算法的用戶。 ***********************************************/ #include <iostream> using namespace std; //--------------------------------------------- // 抽象算法類 // 定義所有支持的算法的公共接口 class Strategy { public: // 算法方法 virtual void vAlgorithmInterface(){}; protected: private: }; //--------------------------------------------- // 具體策略類 // 繼承於算法類,封裝具體的算法或行爲 // 算法A的實現 class ConcreteStrategyA : public Strategy { public: void vAlgorithmInterface() { cout << "算法A的實現" << endl; } protected: private: }; // 算法B的實現 class ConcreteStrategyB : public Strategy { public: void vAlgorithmInterface() { cout << "算法B的實現" << endl; } protected: private: }; // 算法C的實現 class ConcreteStrategyC : public Strategy { public: void vAlgorithmInterface() { cout << "算法C的實現" << endl; } protected: private: }; //--------------------------------------------- // Context上下文類 // 用一方法維護對Strategy對象的引用 // 上下文 class Context { public: // 初始化傳入具體策略對象 Context( Strategy *pstrategy ) : mp_strategy(pstrategy) {}; // 上下文接口 // 根據具體策略對象調用其算法的方法 void vContextInterface() { mp_strategy->vAlgorithmInterface(); } protected: private: Strategy *mp_strategy; };
#pragma once /******************************** * * 策略模式應用:商場收銀<mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js"></mce:script><mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js"></mce:script>系統 * ********************************/ // 現金收費抽象類 class CashSuper { public: // 構造 CashSuper() : dwTotal(0) {}; virtual double dwAcceptCash( double dwMoney ) { dwTotal = dwMoney; return dwTotal; } protected: private: // 總價 double dwTotal; }; // 正常收費子類 class CashNormal : public CashSuper { public: double dwAcceptCash( double dwMoney ) { // 正常收費,原價返回 return dwMoney; } protected: private: }; // 打折收費子類 class CashRebate : public CashSuper { public: CashRebate() : dwMoneyRebate(1){}; CashRebate( double dwMoney ) : dwMoneyRebate(dwMoney) {}; double dwAcceptCash( double dwMoney ) { return dwMoney * dwMoneyRebate; } protected: private: double dwMoneyRebate;// 折扣率 }; // 返利收費子類 class CashReturn : public CashSuper { public: CashReturn() : dwMoneyCondition(300), dwMoneyReturn(100) {}; CashReturn( double dwCondition, double dwReturn ) : dwMoneyCondition(dwCondition), dwMoneyReturn(dwReturn) {}; double dwAcceptCash( double dwMoney ) { double dwResult = dwMoney; if ( dwMoney > dwMoneyCondition ) { // 大於返利條件 dwResult = dwMoney - (int)dwMoney / (int)dwMoneyCondition * dwMoneyReturn; } return dwResult; } protected: private: double dwMoneyCondition; double dwMoneyReturn; }; // 上下文 class CashContext { public: // 構造方法獲取具體收費策略 CashContext( CashSuper *p_cs ) : mp_cashsuper(p_cs) {}; double dwGetResult( double dwMoney ) { // 根據收費策略的不同取得收費結果 return mp_cashsuper->dwAcceptCash( dwMoney ); } protected: private: // 加入CashSuper對象,聚合關係 CashSuper *mp_cashsuper; }; //--------------------------------------------- // 策略與簡單工廠結合 class CashContextF { public: // 構造方法獲取具體收費策略 CashContextF( char cType ) { switch ( cType ) { // 正常 case 'n': case 'N': mp_cashsuper = new CashNormal(); break; // 返利 case 'r': case 'R': mp_cashsuper = new CashReturn( 300, 100 ); break; // 打折 case 't': case 'T': mp_cashsuper = new CashRebate( 0.8 ); break; default: mp_cashsuper = new CashSuper(); break; } }; double dwGetResult( double dwMoney ) { // 根據收費策略的不同取得收費結果 return mp_cashsuper->dwAcceptCash( dwMoney ); } protected: private: // 加入CashSuper對象,聚合關係 CashSuper *mp_cashsuper; };
——By 陳相禮 09/12/02
文章目錄一、逆向工程與正向工程在UML圖中的應用1. UML建模工具:2. UML工具 PowerDesigin 16.5 安裝:3. 名稱解釋:4. 操作流程二、關係(依賴,泛化,關聯,實現)畫法1. 依賴關係(Dependen
UML建模在工程開發中,不止程序員可以用於做軟件程序設計,而且產品經理也常常使用它來做軟件需求分析。它本身的語法複雜度不高,新手經過一段時間的系統練習,很快可以熟悉使用。當軟件需求者和軟件開發者共同遵循這一套標準時,無疑可以大
/************************************************************************ * 命令模式學習筆記[C++] * Author: 陳相禮 * Time: 200
/************************************************************************ * 橋接模式學習筆記[C++] * Author: 陳相禮 * Time: 200
/************************************************************************ * 模板方法模式學習筆記[C++] * Author: 陳相禮 * Time: 2
/************************************************************************ * 建造者模式學習筆記[C++] * Author: 陳相禮 * Time: 20
/************************************************************************ * 類的設計:單一職責原則 * 1、就一個類而言,應該僅有一個引起它變化的原因。 *
/************************************************************************ * 工廠方法模式學習筆記[C++] * Author: 陳相禮 * Time: 2
/************************************************************************ * 代理模式學習筆記[C++] * Author: 陳相禮 * Time: 200
一、繼承關係 繼承指的是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並可以增加它自己的新功能的能力。在Java中繼承關係通過關鍵字extends明確標識,在設計時一般沒有爭議性。在UML類圖設計中,繼承