日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

面向对象设计的五项基本原则

發(fā)布時(shí)間:2024/1/18 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面向对象设计的五项基本原则 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 1.單一職責(zé)原則(SRP: Single Resposibility Principle)
  • 2.開(kāi)放封閉原則(OCP: Open Closed Principle)
  • 3.里氏替換原則(LSP: Liskov Substituion Principle)
  • 4.依賴倒置原則(DIP: Dependecy Inversion Principle)
  • 5.接口分離原則(ISP: Interface Segregation Principle)
  • 6.小結(jié)
  • 參考文獻(xiàn)

面向?qū)ο笤O(shè)計(jì)(OOD)是面向?qū)ο缶幊?#xff08;OOP)必不可少的一個(gè)環(huán)節(jié),只有好的設(shè)計(jì),才能保障程序的質(zhì)量。

面向?qū)ο笤O(shè)計(jì)的主要任務(wù)就是類的設(shè)計(jì),不少面向?qū)ο?#xff08;OO)的先驅(qū)和前輩已經(jīng)提出了很多關(guān)于類的設(shè)計(jì)原則,用于指導(dǎo) OOP,其中就包括類設(shè)計(jì)的五項(xiàng)基本原則。

1.單一職責(zé)原則(SRP: Single Resposibility Principle)

專注是一個(gè)人的優(yōu)良品質(zhì),同樣,單一職責(zé)也是一個(gè)類的優(yōu)良設(shè)計(jì)。單一職責(zé)的核心思想:一個(gè)類只做好一件事情。

單一職責(zé)原則可以看作是高內(nèi)聚、低耦合在面向?qū)ο笤瓌t上的引申。類的職責(zé)過(guò)多,容易導(dǎo)致類間職責(zé)依賴,提高耦合度,降低內(nèi)聚性。通常意義下的單一職責(zé),指的是類只有一種單一功能,不要為類設(shè)計(jì)過(guò)多的功能,交雜不清的功能會(huì)使代碼雜亂,提高程序開(kāi)發(fā)的難度和系統(tǒng)出錯(cuò)的概率,降低系統(tǒng)的可維護(hù)性。

要舉個(gè)體現(xiàn)單一職責(zé)原則的最常見(jiàn)的例子無(wú)疑就是STL中的迭代器的設(shè)計(jì)。有些人覺(jué)得容器跟迭代器的分離是不好的設(shè)計(jì),覺(jué)得增加了復(fù)雜度,不如直接把迭代器放在容器里更為簡(jiǎn)潔。不過(guò)很多人還是不這樣認(rèn)為,因?yàn)轭惖臄?shù)量越多并不代表就越復(fù)雜,另外迭代器如果放到容器里面,就會(huì)暴露容器的一些內(nèi)部結(jié)構(gòu),不太符合封裝的思想。還有就是可擴(kuò)展性的問(wèn)題,因?yàn)閷?duì)容器的訪問(wèn)遍歷會(huì)有多種需求,如果把迭代器隔離開(kāi)來(lái)你可以不修改容器類,再定義些特制的迭代器就行了,這樣不管有什么奇怪的需求只要寫(xiě)個(gè)對(duì)應(yīng)的迭代器出來(lái)就行了。

2.開(kāi)放封閉原則(OCP: Open Closed Principle)

開(kāi)閉原則指的是開(kāi)放封閉原則,即對(duì)擴(kuò)展開(kāi)放,對(duì)修改封閉。

所謂修改封閉,就是之前設(shè)計(jì)好的類,不要去修改。比如刪除掉一個(gè)成員函數(shù)、改變成員函數(shù)的形參列表或更改數(shù)據(jù)成員類型等。實(shí)現(xiàn)對(duì)修改封閉,關(guān)鍵在于抽象化。對(duì)一個(gè)事物抽象化,實(shí)質(zhì)上是對(duì)一個(gè)事物進(jìn)行概括、歸納、總結(jié),將其本質(zhì)特征抽象地用一個(gè)類來(lái)表示,這樣類才會(huì)相對(duì)穩(wěn)定,無(wú)需更改。

所謂擴(kuò)展開(kāi)放,就是在不改變已存在的類的前提下可以添加很多功能。一般是通過(guò)繼承和多態(tài)來(lái)實(shí)現(xiàn),如此一來(lái),可以保持父類的原樣,只需在子類中添加些所需的新功能。

“需求總是變化的”,如果遵循開(kāi)放封閉原則,合理設(shè)計(jì)就能封閉變化,使類能夠靈活的擴(kuò)展所需的功能。

3.里氏替換原則(LSP: Liskov Substituion Principle)

Liskov 替換原則指的是:子類可以替換父類并出現(xiàn)在父類能夠出現(xiàn)的任何地方。這個(gè)原則是 Liskov 于1987年提出,它同樣可以從 Bertrand Meyer的 DBC(Design by Contract,按契約設(shè)計(jì))的概念推出。

C++ 語(yǔ)言機(jī)制將類的抽象與多態(tài)建立在繼承的基礎(chǔ)上,其實(shí)現(xiàn)的方法是面向接口編程:通過(guò)提取純虛類(Abstract Class),將公共部分抽象為基類接口或由子類重寫(xiě)覆蓋基類方法來(lái)達(dá)到多態(tài)的目的。Liskov 替換原則的作用就是為了保證繼承復(fù)用的可靠。

下面來(lái)舉個(gè)違反替換原則的特殊例子:
正方形與長(zhǎng)方形的問(wèn)題也是屬于“圓不是橢圓”這類問(wèn)題。我們知道正方形是一個(gè)特殊的長(zhǎng)方形,所以可以設(shè)計(jì)兩個(gè)類,正方形類繼承自長(zhǎng)方形類。長(zhǎng)方形類有兩個(gè)成員變量,分別表示長(zhǎng)和寬,有個(gè)計(jì)算面積的成員函數(shù)。假如計(jì)算面積的方法是virtual的,這樣能實(shí)現(xiàn)多態(tài)。在先設(shè)定長(zhǎng)和寬后再調(diào)用計(jì)算面積的方法。我們知道正方形是長(zhǎng)和寬相等的,如果設(shè)定長(zhǎng)和寬的時(shí)候不是一樣的,然后調(diào)用了正方形的面積計(jì)算公式,這樣肯定就錯(cuò)了。你可能會(huì)問(wèn)咋這么扯蛋啊,為啥把長(zhǎng)和寬設(shè)成不一樣啊。很多設(shè)計(jì)思想和方法是一來(lái)為了方便,二來(lái)為了讓用戶少犯錯(cuò)誤,就是不管你怎么使用都不會(huì)出錯(cuò),要出錯(cuò)應(yīng)該是在編譯時(shí)出錯(cuò),放置運(yùn)行時(shí)出錯(cuò)。如果出現(xiàn)上面說(shuō)的情況編譯器是沒(méi)法讓你知道出錯(cuò)了的。

所以一個(gè)正方形類繼承自長(zhǎng)方形類的設(shè)計(jì)是不好的(注意的一點(diǎn)是你違反了 Liskov 替換原則并不是說(shuō)就寫(xiě)的代碼就會(huì)出錯(cuò),只是說(shuō)設(shè)計(jì)不太合理。實(shí)際上你這樣設(shè)計(jì)代碼沒(méi)準(zhǔn)可以正常的跑得很好呢,如果沒(méi)有出現(xiàn)一些特殊情況可能是一點(diǎn) bug 也沒(méi)有,只不過(guò)設(shè)計(jì)不合理為導(dǎo)致一些安全隱患而已)。

4.依賴倒置原則(DIP: Dependecy Inversion Principle)

其核心思想是:依賴于抽象。具體而言就是高層模塊不依賴于底層模塊,二者都依賴于抽象;抽象不依賴于具體,具體依賴于抽象。依賴倒置原則是對(duì)傳統(tǒng)過(guò)程性設(shè)計(jì)方法的“倒轉(zhuǎn)”,是高層次模塊復(fù)用及其可維護(hù)性的有效規(guī)范。

依賴一定存在于類與類、模塊與模塊之間。類與類之間產(chǎn)生依賴時(shí),依賴倒置原則的理解可以描述如下:依賴就是剛開(kāi)始時(shí)具體細(xì)節(jié)間互相依賴,我們將實(shí)現(xiàn)的細(xì)節(jié)變成抽象類,降低類間耦合度。然后有了抽象類,繼承自它的實(shí)現(xiàn)類也要依賴它。那倒置兩字咋理解呢? 一般情況我們是先關(guān)注細(xì)節(jié),然后根據(jù)細(xì)節(jié)抽象出來(lái)一些概括的方法,所以按常理一般是抽象要依賴于細(xì)節(jié)的,而現(xiàn)在是是倒過(guò)來(lái)了,確定一個(gè)抽象類后,那些細(xì)節(jié)的實(shí)現(xiàn)得以抽象出來(lái)的方法為基準(zhǔn),變成了細(xì)節(jié)依賴于抽象了,不然你要繼承了一個(gè)抽象類,你不完全實(shí)現(xiàn)它的方法的話可不讓你實(shí)例化對(duì)象的啊。

當(dāng)兩個(gè)模塊之間存在緊密的耦合關(guān)系時(shí),最好的方法就是分離接口和實(shí)現(xiàn):在依賴之間定義一個(gè)抽象的接口,供高層模塊調(diào)用,底層模塊實(shí)現(xiàn)接口的定義,從而有效控制耦合關(guān)系,達(dá)到依賴于抽象的設(shè)計(jì)目的。

依賴于抽象就是不對(duì)實(shí)現(xiàn)編程,而對(duì)接口編程。依賴于抽象是一個(gè)通用原則,而有些時(shí)候依賴于細(xì)節(jié)是在所難免的,我們需要根據(jù)具體情況在在抽象與具體之間進(jìn)行取舍。

5.接口分離原則(ISP: Interface Segregation Principle)

該原則的核心思想是:使用多個(gè)小的專門(mén)的接口,而不要使用一個(gè)大的總接口。具體而言,接口應(yīng)該是內(nèi)聚的,應(yīng)該避免“胖”接口。一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口上,而不要強(qiáng)迫依賴不同的方法,這是一種接口污染。

其實(shí)簡(jiǎn)單點(diǎn)的講與前面說(shuō)的單一職責(zé)類似,這里的接口不是函數(shù)接口,而是一個(gè)類。C#中的有專門(mén)的接口interface,和類區(qū)分開(kāi)來(lái),而且C#中不像C++支持類的多繼承,只支持接口的多繼承,所以這里可以把接口理解成功能更小更特殊的類,一個(gè)接口可能就只要那么幾個(gè)很少的方法就OK了。

接口分離手段主要有以下兩種方式:
(1)利用委托分離接口;
(2)利用多重繼承分離接口。

6.小結(jié)

概括地講,面向?qū)ο笤O(shè)計(jì)原則仍然是面向?qū)ο笏枷氲捏w現(xiàn)。例如,

  • 單一職責(zé)原則要求類只負(fù)責(zé)一件事情;
  • 接口分離原則,讓客戶只關(guān)心他們所需的接口。單一職責(zé)原則與接口分離原都體現(xiàn)了內(nèi)聚的思想;
  • 開(kāi)放封閉原則,要求類不作修改而能夠擴(kuò)展功能,體現(xiàn)了類的封裝與繼承;
  • Liskov 替換原則,要求派生類要能夠替換基類,是對(duì)類繼承的規(guī)范;
  • 依賴倒置原則,要求類依賴于抽象,而不是實(shí)現(xiàn),是抽象思想的體現(xiàn)。

上面五條面向?qū)ο笤O(shè)計(jì)原則,可以幫助我們?cè)O(shè)計(jì)出代碼易復(fù)用、功能易擴(kuò)展、維護(hù)易進(jìn)行的程序,需要我們?cè)趯?shí)踐中遵守。


參考文獻(xiàn)

類設(shè)計(jì)的5個(gè)基本原則
李健.編寫(xiě)高質(zhì)量代碼:改善C++程序的150個(gè)建議[M].第一版.北京:機(jī)械工業(yè)出版社,2012.1:316-317

總結(jié)

以上是生活随笔為你收集整理的面向对象设计的五项基本原则的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。