C#六大設(shè)計(jì)原則_第1頁(yè)
C#六大設(shè)計(jì)原則_第2頁(yè)
C#六大設(shè)計(jì)原則_第3頁(yè)
C#六大設(shè)計(jì)原則_第4頁(yè)
C#六大設(shè)計(jì)原則_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、C狀大設(shè)計(jì)原則2020-7-7蝌蚪成長(zhǎng)記c#程序設(shè)計(jì)目錄C#六大設(shè)計(jì)原則2單一職責(zé)原則 2接口隔離原則 5開(kāi)閉原則9里氏替換原則12依賴(lài)倒置原則 1.3迪米特法則.6C#六大設(shè)計(jì)原則筆者作為一個(gè)菜鳥(niǎo),會(huì)嘗試以簡(jiǎn)單的代碼和容易理解的語(yǔ)句去解釋這幾種原則的特性和應(yīng)用場(chǎng)景。這六種原則分別為單一職責(zé)原則、接口隔離原則、里氏替換原則、迪米特法則、依賴(lài)倒置原則、開(kāi)閉原則。單一職責(zé)原則單一職責(zé)原則(SRP : Single responsibility principle) ,規(guī)定一個(gè)類(lèi)中應(yīng)該只有一個(gè)原因引起類(lèi)的變化。單一職責(zé)原則的核心就是解耦和增強(qiáng)內(nèi)聚性。問(wèn)題:/假設(shè)此類(lèi)是數(shù)據(jù)庫(kù)上下文public cla

2、ss DatabaseContext public class Testprivate readonly DatabaseContext _context;public T est(DatabaseContext context)_context = context;/用戶(hù)登錄public void UserLogin() /用戶(hù)注銷(xiāo)public void UserLogout() /新增一個(gè)用戶(hù)public void AddUser() /修改一個(gè)用戶(hù)的信息public void UpdateUser() /刪除一個(gè)用戶(hù)public void DeleteUser() Test負(fù)責(zé) 職責(zé)P1

3、(用戶(hù)登錄和退出)和P2(用戶(hù)賬號(hào)管理)兩個(gè)職責(zé),當(dāng)由于 職責(zé)P1的需求發(fā)生變化而需要修改類(lèi)時(shí),有可能會(huì)導(dǎo)致正常職責(zé) P2的功能發(fā)生故障。上面的代碼中,兩個(gè)職責(zé)被耦合起來(lái),擔(dān)任了多種功能。一個(gè)類(lèi)中應(yīng)該只有一個(gè)原因引起類(lèi)的變化,也就要求一個(gè)類(lèi)只應(yīng)該負(fù)責(zé)一個(gè)功能,類(lèi)中地代碼是緊密聯(lián)系的。上面的示例代碼非常簡(jiǎn)單,我們可以很自然地將一個(gè)個(gè)類(lèi)分為兩個(gè)部分。/假設(shè)此類(lèi)是數(shù)據(jù)庫(kù)上下文public class DatabaseContext public class Testiprivate readonly DatabaseContext _context;public T est1(DatabaseCon

4、text context)_context = context;/用戶(hù)登錄public void UserLogin() /用戶(hù)注銷(xiāo)public void UserLogout() public class Test2private readonly DatabaseContext _context;public T est2(DatabaseContext context)_context = context;/新增一個(gè)用戶(hù)public void AddUser() /修改一個(gè)用戶(hù)的信息public void UpdateUser() /刪除一個(gè)用戶(hù)public void DeleteUse

5、r() 因此,單一職責(zé)原則的解決方法,是將不同職責(zé)封裝到不同的類(lèi)或模塊中。接口隔離原則接口隔離原則(ISP: Interface Segregation Principle) 要求對(duì)接口進(jìn)行細(xì)分, 類(lèi)的繼承建立在最小的粒度上,確保客戶(hù)端繼承的接口中,每一個(gè)方法都是它 需要的。筆者查閱了國(guó)外一些資料,大多將接口隔離原則定義為:“ Clients should not be forced to depend upon interfaces that they do not use. ”意思是不應(yīng)強(qiáng)迫客戶(hù)依賴(lài)于它不使用的方法。這就要求我們拆分臃月中的接口成為更小的和更具體的接口,使得接口負(fù)責(zé)的功 能

6、更加單一。目的:通過(guò)將軟件分為多個(gè)獨(dú)立的部分來(lái)減少所需更改的副作用和頻率。筆者想到從兩方面論述:其一,在描述多種動(dòng)物時(shí),我們可能會(huì)將不同種類(lèi)的動(dòng)物分類(lèi)。但是這還不夠,例如在鳥(niǎo)類(lèi)中,我們印象中鳥(niǎo)的特征是鳥(niǎo)會(huì)飛,但是企鵝不會(huì)飛那么還要對(duì)物種的特征進(jìn)行細(xì)分,例如血液是什么顏色的、有沒(méi)有脊椎等。其二,我們可以通過(guò)下面代碼表達(dá):/與登錄有關(guān)public interface lUserLogin(/登錄void Login();/注銷(xiāo)void Logout();/與用戶(hù)賬號(hào)有關(guān)public interface lUserlnfo(/新增一個(gè)用戶(hù)void AddUser();/修改一個(gè)用戶(hù)的信息void U

7、pdateUser();/刪除一個(gè)用戶(hù)void DeleteUser();上面的兩個(gè)接口,各種實(shí)現(xiàn)不同的功能,彼此沒(méi)有交叉,完美接下來(lái)我們看看兩個(gè)繼承了lUserLogin 接口的代碼/對(duì)用戶(hù)登錄注銷(xiāo)進(jìn)行管理,資源準(zhǔn)備和釋放public class Testi : lUserLogin(public void Login()public void Logout()public class Test2 : lUserLoginpublic void Login()/獲取用戶(hù)未讀消息public void Logout()對(duì)于Testi ,根據(jù)登錄和注銷(xiāo)兩個(gè)狀態(tài),進(jìn)行不同操作。但是,對(duì)于Test2

8、,它只需要登錄這個(gè)狀態(tài),其它情況不關(guān)它事。那么Logout()對(duì)他來(lái)說(shuō),完全沒(méi)有用,這就是接口污染。上面的代碼就違法了接口隔離原則。但是,接口隔離原則有個(gè)缺點(diǎn),就是容易過(guò)多地將細(xì)分接口。一個(gè)項(xiàng)目中,出 現(xiàn)成千上萬(wàn)個(gè)接口,將是維護(hù)地災(zāi)難。因此接口隔離原則要靈活使用,就 Test2來(lái)說(shuō),多繼承一個(gè)方法無(wú)傷大礙,不 用就是了。ASP.NET Core中就存在很多這樣的實(shí)現(xiàn)。public void Function()(throw new NotImplementedException();)設(shè)計(jì)模式之禪第四章中,作者對(duì)接口隔離原則總結(jié)了四個(gè)要求:1接口盡量小:不出現(xiàn)臃月中(Fat)的接口。2接口要高

9、內(nèi)聚:提高接口、類(lèi)、模塊的處理能力。3定制服務(wù):小粒度的接口可以組成大接口,靈活定制新的功能。4接口的設(shè)計(jì)有限度:難以有固定的標(biāo)準(zhǔn)去衡量接口的粒度是否合理。另外還有關(guān)于單一職責(zé)原則和接口隔離原則的關(guān)系和對(duì)比單一職責(zé)原則是從服務(wù)提供者的角度去看,提供一個(gè)高內(nèi)聚的、單一職責(zé)的功 能;接口隔離原則是從使用者角度去看,也是實(shí)現(xiàn)高內(nèi)聚和低耦合。接口隔離原則的粒度可能更小,通過(guò)多個(gè)接口靈活組成一個(gè)符合單一職責(zé)原則 的類(lèi)。我們也看到了,單一職責(zé)原則更多是圍繞類(lèi)來(lái)討論;接口隔離原則是對(duì)接口來(lái) 討論,即對(duì)抽象進(jìn)行討論。開(kāi)閉原則開(kāi)閉原則(Open/Closed Principle)規(guī)定:“軟件中的對(duì)象(類(lèi),模塊,

10、函數(shù)等等)應(yīng)該對(duì)于擴(kuò)展是開(kāi)放的,但是對(duì)于修 改是封閉的”-«Object-Oriented Software Construction 作者 Bertrand Meyer開(kāi)閉原則意味著一個(gè)實(shí)體是允許在不改變它的源代碼的前提下變更它的行為。類(lèi)的改動(dòng)是通過(guò)增加代碼實(shí)現(xiàn),而不是修改源代碼。開(kāi)閉原則 有 梅耶開(kāi)閉原則、多態(tài)開(kāi)閉原則。梅耶開(kāi)閉原則代碼一旦完成,一個(gè)類(lèi)的實(shí)現(xiàn)只應(yīng)該因錯(cuò)誤而修改,新的或者改變的特性應(yīng)該通過(guò)新建不同的類(lèi)實(shí)現(xiàn)。特點(diǎn):繼承,子類(lèi)繼承父類(lèi),擁有其所有的方法,并且拓展。多態(tài)開(kāi)閉原則此原則使用接口而不是父類(lèi)來(lái)允許不同的實(shí)現(xiàn),您可以在不更改它們的代碼的情況下輕松替換它們。現(xiàn)在大多

11、數(shù)情況下,開(kāi)閉原則指的是多態(tài)開(kāi)閉原則。多態(tài)開(kāi)閉原則筆者在查閱資料是,發(fā)現(xiàn)這個(gè)接口指的不是Interface ,指的是抽象方法、虛方法。問(wèn):面向?qū)ο蟮娜筇匦允鞘裁矗看穑悍庋b、繼承、多態(tài)。對(duì),多態(tài)開(kāi)閉原則就是指這個(gè)多態(tài)。不過(guò),原則要求不應(yīng)對(duì)方法進(jìn)行重載(重寫(xiě))、隱藏。這是一個(gè)示例:/實(shí)現(xiàn)登錄注銷(xiāo)public class UserLogin(public void Login() public void Logout() public virtual void A() /*做了一些事*/)public virtual void B() /* 也做了一些事 */ )public class User

12、Loginl : UserLoginpublic void Login(string userName) /應(yīng)不應(yīng)該對(duì)父類(lèi)的方法進(jìn)行重載?public override void A() /Vpublic override void B() /Vpublic new void Logout() / 也許行?多態(tài)開(kāi)閉原則的好處是,引入了抽象,使得兩個(gè)類(lèi)松耦合,而且可以使得在不 修改代碼的前提下,使用子類(lèi)替換父類(lèi)(里氏替換原則)。有時(shí),會(huì)看到這樣的題目:接口和抽象類(lèi)的區(qū)別?筆者隱約記得有過(guò)一條這樣的解釋?zhuān)航涌谑菫榱藢?shí)現(xiàn)共同的標(biāo)準(zhǔn);抽象是為了 代碼的復(fù)用。當(dāng)然,接口和抽象,都可以實(shí)現(xiàn)里氏替換。通過(guò)開(kāi)

13、閉原則,我們可以了解到多態(tài),也了解接口和抽象的應(yīng)用場(chǎng)景。還有一個(gè)問(wèn)題是,開(kāi)閉原則要求是要修改或添加功能時(shí),通過(guò)子類(lèi)來(lái)實(shí)現(xiàn),而 不是修改原有代碼。那么是否可以和應(yīng)該對(duì)父類(lèi)的代碼進(jìn)行重載和隱藏?而開(kāi)閉原則的核心是構(gòu)造抽象,從而通過(guò)子類(lèi)派生來(lái)實(shí)現(xiàn)拓展。貌似沒(méi)有說(shuō)到這方面。筆者覺(jué)得不太應(yīng)該。先結(jié)合下面的里氏替換原則,我們?cè)儆懻撨@個(gè)問(wèn)題?里氏替換原則里氏替換原則(LSP: Liskov Substitution Principle) 要求:凡是父類(lèi)出現(xiàn)的地方,子類(lèi)都可以出現(xiàn)。這就要求了子類(lèi)必須與父類(lèi)具有相同的行為。只有當(dāng)子類(lèi)能夠替換任何父類(lèi)的實(shí)例時(shí),才會(huì)符合里氏替換原則。里氏替換原則的約束:1子類(lèi)必須實(shí)

14、現(xiàn)父類(lèi)的抽象方法,但不能重寫(xiě)父類(lèi)中已實(shí)現(xiàn)的方法。2子類(lèi)中可以增加方法拓展功能。3當(dāng)子類(lèi)覆蓋或?qū)崿F(xiàn)(虛擬方法/抽象方法)父類(lèi)的方法時(shí),方法的輸入?yún)?shù)限制 更加寬松并且返回值要比父類(lèi)方法更加嚴(yán)格。所以,我們看到開(kāi)閉原則中的示例,子類(lèi)應(yīng)不應(yīng)該重載父類(lèi)的方法?應(yīng)不應(yīng)該 使用new關(guān)鍵字隱藏父類(lèi)的方法?為了確保子類(lèi)繼承后,還具有跟父類(lèi)一致 的特性,不建議這樣做呢,親。實(shí)現(xiàn)了開(kāi)閉原則,自然可以使用里氏替換原則依賴(lài)倒置原則依賴(lài)倒置原則(Dependence Inversion Principle )要求程序要依賴(lài)于抽象接口,不要依賴(lài)于具體實(shí)現(xiàn)。我們可以從代碼中,慢慢演進(jìn)和推導(dǎo)理論。/實(shí)現(xiàn)登錄注銷(xiāo)public

15、 class UserLogin(public void Login()public void Logout()public class Test1 : UserLogin public class Test2private readonly UserLogin userLogin = new UserLogin();public class Test3private readonly UserLogin _userLogin;public T est3(UserLogin userLogin)_userLogin = userLogin;)O先不說(shuō)上面代碼有什么毛病,根上面代碼中,Testi

16、、Test2、Test3 都依賴(lài) UserLogin 據(jù)依賴(lài)倒置原則,應(yīng)該是這樣編寫(xiě)代碼的。/與登錄有關(guān)public interface lUserLogin(void Login(); / 登錄void Logout(); / 注銷(xiāo))/實(shí)現(xiàn)登錄注銷(xiāo)public class UserLoginl : lUserLogin(public void Login()public void Logout()/實(shí)現(xiàn)登錄注銷(xiāo)public class UserLogin2 : lUserLoginpublic void Login()public void Logout()public class Test4private readonly IUserLogin _userLogin;public T est4(IUserLogin userLogin)_userLogin = userLogin;依賴(lài)倒置原則,在于引入一種抽象,這種抽象將高級(jí)模塊和底層模塊彼此分 離。高層模塊和底層模塊松耦合,底層模塊的變動(dòng)不需要高層模塊也要變動(dòng)依賴(lài)導(dǎo)致原則有兩個(gè)思想:1高層模塊不應(yīng)該依賴(lài)于底層模塊,兩者都應(yīng)該依賴(lài)于抽象。2抽象不應(yīng)該依賴(lài)細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴(lài)于抽象。因?yàn)橐蕾?lài)于抽象,底層模塊可以任意替換一個(gè)實(shí)現(xiàn)了抽象

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論