C#设计模式(2)
問題所在?? 設計目標
----------------------------------------------------------------------------
過于僵硬?? 可擴展性(新性能可以很容易加入系統)
過于脆弱?? 靈活性(修改不會波及其它)
復用率低??
粘度過高?? 可插入性(新功能容易加入系統(氣囊加入方向盤))
* 提高系統可復用性的幾點原則:
傳統復用:
1. 代碼的粘帖復用
2. 算法的復用
3. 數據結構的復用
* 可維護性與可復用性并不完全一致
* 對可維護性的支持:
一、 "開放-封閉"原則(OCP)
Open-Closed Principle原則講的是:一個軟件實體應當對擴展開放,對修改關閉。
優點:
??? 通過擴展已有軟件系統,可以提供新的行為,以滿足對軟件的新的需求,使變化中的軟件有一定的適應性和靈活性。
??? 已有軟件模塊,特別是最重要的抽象層模塊不能再修改,這使變化中的軟件系統有一定的穩定性和延續性。
例子:玉帝招安美猴王
當年大鬧天宮便是美猴王對玉帝的新挑戰。美猴王說:"'皇帝輪流做,明年到我家。'只教他搬出去,將天宮讓于我!"對于這項挑戰,太白金星給玉皇大帝提出的建議是:"降一道招安圣旨,宣上界來…,一則不勞師動眾,二則收仙有道也。"
換而言之,不勞師動眾、不破壞天規便是"閉",收仙有道便是"開"。招安之道便是玉帝天庭的"開放-封閉"原則。
?
招安之法的關鍵便是不允許更改現有的天庭秩序,但允許將妖猴納入現有秩序中,從而擴展了這一秩序。用面向對象的語言來講,不允許更改的是系統的抽象層,而允許更改的是系統的實現層。
二、 里氏代換原則(LSP)
Liskov Substitution Principle(里氏代換原則):子類型(subtype)必須能夠替換它們的基類型。
白馬、黑馬
?
反過來的代換不成立
《墨子·小取》說:"娣,美人也,愛娣,非愛美人也……"娣便是妹妹,哥哥喜愛妹妹,是因為兩人是兄妹關系,而不是因為妹妹是個美人。因此,喜愛妹妹不等同于喜愛美人。用面向對象語言描述,美人是基類,妹妹是美人的子類。哥哥作為一個有"喜愛()"方法,接受妹妹作為參數。那么,這個"喜愛()"方法一般不能接受美人的實例。
?
一個違反LSP的簡單例子(長方形和正方形)
public?class?Rectangle{
???private?long?width;
???private?long?height;
????
???public?void?setWidth(long?width)
???{
??????this.width?=?width;
???}
???public?long?getWidth()
???{
??????return?this.width;
???}
???public?void?setHeight(long?height)
???{
??????this.height?=?height;
???}
???public?long?getHeight()
???{
??????return?this.height;
???}
}
public?class?Square
{
???private?long?side;
????
???public?void?setSide(long?side)
???{
??????this.side?=?side;
???}
???public?long?getSide()
???{
??????return?side;
???}
}
正方形不可以做長方形的子類
public?class?Rectangle
{
???private?long?width;
???private?long?height;
????
???public?void?setWidth(long?width)
???{
??????this.width?=?width;
???}
???public?long?getWidth()
???{
??????return?this.width;
???}
???public?void?setHeight(long?height)
???{
??????this.height?=?height;
???}
???public?long?getHeight()
???{
??????return?this.height;
???}
}
public?class?Square?:?Rectangle
{
???private?long?side;
???public?void?setWidth(long?width)
???{
??????setSide(width);
???}
???public?long?getWidth()
???{
??????return?getSide();
???}
???public?void?setHeight(long?height)
???{
??????setSide(height);
???}
???public?long?getHeight()
???{
??????return?getSide();
???}
???public?long?getSide()
???{
??????return?side;
???}
???public?void?setSide(long?side)
???{
??????this.side?=?side;
???}
}
public?class?SmartTest
{
???public?void?resize(Rectangle?r)
???{
??????while?(r.getHeight()?>=?r.getWidth()?)
??????{
?????????r.setWidth(r.getWidth()?+?1);
??????}
???}
}
?
在執行SmartTest的resize方法時,如果傳入的是長方形對象,當高度大于寬度時,會自動增加寬度直到超出高度。但是如果傳入的是正方形對象,則會陷入死循環。
代碼重構
public?interface?Quadrangle{
???public?long?getWidth();
???public?long?getHeight();
}
public?class?Rectangle?:?Quadrangle?
{
???private?long?width;
???private?long?height;
????
???public?void?setWidth(long?width)
???{
??????this.width?=?width;
???}
???public?long?getWidth()
???{
??????return?this.width;
???}
???public?void?setHeight(long?height)
???{
??????this.height?=?height;
???}
???public?long?getHeight()
???{
??????return?this.height;
???}
}
public?class?Square?:?Quadrangle?
{
???private?long?side;
???public?void?setSide(long?side)
???{
??????this.side?=?side;
???}
???public?long?getSide()
???{
??????return?side;
???}
???public?long?getWidth()
???{
??????return?getSide();
???}
???public?long?getHeight()
???{
??????return?getSide();
???}
}
?
轉載于:https://www.cnblogs.com/xujiaci/archive/2007/09/28/909267.html
總結
- 上一篇: 使用openswan构建lan-to-l
- 下一篇: c# char unsigned_dll