題目:做乙個商場收銀軟體,營業員根據客戶所購買商品的單價和數量,向客戶收費。
方案一:用兩個文字框來輸入單價和數量,乙個確定按鈕來算出每種商品的費用,用個列表框來記錄商品的清單,乙個標籤來記錄總計,還需要乙個重置按鈕來重新開始。
商場收銀系統v1.0關鍵**
double total =
0.0d;
private
void
btnok_click
(object sender,
eventargs e)
存在問題新增需求,商場搞活動,所有商品打八折,如何?若只在totalprice乘以0.8,則活動結束難道還要再改一遍**,重新給所有機器安裝一次?顯然是不合適的。那麼考慮加個下拉選擇框呢?
方案二
商場收銀系統v1.1關鍵**
double total =
0d;private
void
form2_load
(object sender,
eventargs e));
cmbtype.selectedindex =0;
}private
void
btnok_click
(object sender,
eventargs e)
total = total + totalprice;
lbxlist.items.
add(
"單價:"
+ txtprice.text +
" 數量:"
+ txtnum.text +
" "+ cmbtype.selecteditem +
" 合計:"
+ totalprice.
tostring()
);lblresult.text = total.
tostring()
;}
存在問題:靈活性好多了,但重複**很多,如convert.todouble()
4個分支除折扣不一樣以外幾乎沒有不同,應該考慮重構
新增需求,活動加大,需要有滿300返100的**演算法,怎麼辦?
方案三:用前面學過的簡單工廠模式,寫乙個父類和多個打折和返利的子類,利用多型實現。
注意不是寫多個子類,只寫兩個子類即可,打折和返利只是傳參不同。
物件導向的程式設計,並不是類越多越好,類的劃分是為了封裝,但分類的基礎是抽象,具有相同屬性和功能的物件的抽象集合才是類。
///
/// 現金收費抽象類
///
abstract
class
cashsuper
///
/// 正常收費子類
///
class
cashnormal
:cashsuper
}///
/// 打折收費子類
///
class
cashrebate
:cashsuper
public
override
double
acceptcash
(double money)
}///
/// 返利收費子類
///
class
cashreturn
:cashsuper
public
override
double
acceptcash
(double money)
}///
/// 現金收費工廠類
///
class
cashfactory
return cs;
}}
客戶端關鍵**
double total =
0d;private
void
form3_load
(object sender,
eventargs e));
cmbtype.selectedindex =0;
}private
void
btnok_click
(object sender,
eventargs e)
存在問題:簡單工廠模式只是解決物件的建立問題
,而且由於工廠本身包括了所有的收費方式,商場是可能經常性的更改打折額度和返利額度,每次維護或擴充套件收費方式都要改動這個工廠,以致**需要重新編譯部署。
方案四:策略模式(strategy) 定義了演算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變化,不會影響到使用演算法的使用者。
策略模式結構圖
因此,cashsuper、cashnormal、cashrebate、cashreturn不用改,新增策略類,修改客戶端即可
///
/// 現金收費策略類
///
class
cashcontext
public
double
getresult
(double money)
}
客戶端
private
void
form4_load
(object sender,
eventargs e));
cmbtype.selectedindex =0;
}private
void
btnok_click
(object sender,
eventargs e)
double totalprice = cc.
getresult
(convert.
todouble
(txtprice.text)
* convert.
todouble
(txtnum.text));
total = total + totalprice;
lbxlist.items.
add(
"單價:"
+ txtprice.text +
" 數量:"
+ txtnum.text +
" "+ cmbtype.selecteditem +
" 合計:"
+ totalprice.
tostring()
);lblresult.text = total.
tostring()
;}
存在問題:又回到方案二的情況,在客戶端去判斷使用哪個演算法,怎麼樣才能把判斷過程從客戶端移走呢?
方案五:策略模式(strategy) +工廠模式
///
/// 改造後的現金收費策略類
///
class
cashcontext1
this
.cs = cs1;
}public
double
getresult
(double money)
}
客戶端**
double total =
0d;private
void
form4_load
(object sender,
eventargs e));
cmbtype.selectedindex =0;
}private
void
btnok_click
(object sender,
eventargs e)
總結:對比一下簡單工廠模式和策略模式,會發現,簡單工廠模式需要客戶端認識cashsuper和cashfactory兩個類,而策略模式只需要客戶端認識cashcontext即可。
策略模式解析:
大話設計模式二 策略模式(商場促銷)
策略模式 它定義了演算法家族,分別封裝起來,讓它們之間可以相互替換,此模式讓演算法的變化,不會影響到使用的演算法客戶。應用案例 商場 的多樣性 折扣,滿減,積分 package strategy abstract class cashsuper class cashnormal extends ca...
商場促銷 策略模式(設計模式)
商場收銀時,如何 用打折還是返利,其實都是一些演算法,用工廠來生成演算法物件,這沒有錯,但演算法本身只是一種策略,最重要的是這些演算法是隨時都可能互相替換的,就這點變化,而封裝變化點是我們物件導向的一種很重要的思維方式。來看看策略模式的結構圖和基本 策略模式 strategy 定義了演算法家族,分別...
策略模式 商場促銷
封裝的簡單策略類 ifndef stratege h define stratege h include using namespace std class stratege class concretestrategea public stratege class concretestratege...