c 物件導向設計五大原則

2022-09-26 18:24:12 字數 3112 閱讀 3266

物件導向設計(ood)是物件導向程式設計(oop)必不可少的乙個環節,只有好的設計,才能保障程式的質量。物件導向設計的主要任務就是類的設計,不少物件導向(oo)的先驅和前輩已經提出了很多關於類的設計原則,用於指導oop,其中就包括類設計的五項基本原則。

1.單一職責原則(single resposibility principle,srp)

專注是乙個人的優良品質,同樣,單一職責也是乙個類的優良設計。單一職責的核心思想:乙個類只做好一件事情。

單一職責原則可以看作是高內聚、低耦合在物件導向原則上的引申。類的職責過多,容易導致類間職責依賴,提高耦合度,降低內聚性。通常意義下的單一職責,指的是類只有一種單一功能,不要為類設計過多的功能,交雜不清的功能會使**雜亂,提高程式開發的難度和系統出錯的概率,降低系統的可維護性。

要舉個體現單一職責原則的最常見的例子無疑就是stl中的迭代器的設計。有些人覺得容器跟迭代器的分離是不好的設計,覺得增加了複雜度,不如直接把迭代器放在容器裡更為簡潔。不過很多人還是不這樣認為,因為類的數量越多並不代表就越複雜,另外迭代器如果放到容器裡面,就會暴露容器的一些內部結構,不太符合封裝的思想。還有就是可擴充套件性的問題,因為對容器的訪問遍歷會有多種需求,如果把迭代器隔離開來你可以不修改容器類,再定義些特製的迭代器就行了,這樣不管有什麼奇怪的需求只要寫個對應的迭代器出來就行了。

2.開放封閉原則(open closed principle,ocp)

開閉原則指的是開放封閉原則,即對擴充套件開放,對修改封閉。

所謂修改封閉,就是之前設計好的類,不要去修改。比如刪除掉乙個成員函式、改變成員函式的形參列表或更改資料成員型別等。實現對修改封閉,關鍵在於抽象化。對乙個事物抽象化,實質上是對乙個事物進行概括、歸納、總結,將其本質特徵抽象地用乙個類來表示,這樣類才會相對穩定,無需更改。

所謂擴充套件開放,就是在不改變已存在的類的前提下可以新增很多功能。一般是通過繼承和多型來實現,如此一來,可以保持父類的原樣,只需在子類中新增些所需的新功能。

「需求總是變化的如果遵循開irxjqafr放封閉原則,合理設計就能封閉變化,使類能夠靈活的擴充套件所需的功能。

3.黎克特制替換原則(liskov substituion principle,lsp)

liskov替換原則指的是:子類可以替換父類並出現在父類能夠出現的任何地方。這個原則是liskov於2023年提出,它同樣可以從bertrand meyer的dbc(design by contract,按契約設計)的概念推出。

c++語言機制將類的抽象與多型建立在繼承的基礎上,其實現的方法是面向介面程式設計:通過提取純虛類(abstract class),將程式設計客棧公共部irxjqafr分抽象為基類介面或由子類重寫覆蓋基類方法來達到多型的目的。liskov替換原則的作用就是為了保證繼承復用的可靠。

下面來舉個違反替換原則的特殊例子:

正方形與長方形的問題也是屬於「圓不是橢圓」這類問題。我們知道正方形是乙個特殊的長方形,所以可以設計兩個類,正方形類繼承自長方形類。長方形類有兩個成員變數,分別表示長和寬,有個計算面積的成員函式。假如計算面積的方法是virtual的,這樣能實現多型。在先設定長和寬後再呼叫計算面積的方法。我們知道正方形是長和寬相等的,如果設定長和寬的時候不是一樣的,然後呼叫了正方形的面積計算公式,這樣肯定就錯了。你可能會問咋這麼扯蛋啊,為啥把長和寬設成不一樣啊。很多設計思想和方法是一來為了方便,二來為了讓使用者少犯錯誤,就是不管你怎麼使用都不會出錯,要出錯應該是在編譯時出錯,放置執行時出錯。如果出現上面說的情況編譯器是沒法讓你知道出錯了的。

所以乙個正方形類繼承自長方形類的設計是不好的(注意的一點是你違反了liskov替換原則並不是說就寫的**就會出錯,只是說設計不太合理。實際上你這樣設計**沒準可以正常的跑得很好呢,如果沒有出現一些特殊情況可能是一點bug也沒有,只不過設計不合理為導致一些安全隱患而已)。

4. 依賴倒置原則(dependecy inversion principle,dip)

其核心思想是:依賴於抽象。具體而言就是高層模組不依賴於底層模組,二者都依賴於抽象;抽象不依賴於具體,具體依賴於抽象。依賴倒置原則是對傳統過程性設計方法的「倒轉」,是高層次模組復用及其可維護性的有效規範。

依賴一定存在於類與類、模組與模組之間。類與類之間產生依賴時,依賴倒置原則的理解可以描述如下:依賴就是剛開始時具體細節間互相依賴,我們將實現的細節變成抽象類,降低類間耦合度。然後有了抽象類,繼承自它的實現類也要依賴它。那倒置兩字咋理解呢? 一般情況我們是先關注細節,然後根據細節抽象出來一些概括的方法,所以按常理一般是抽象要依賴於細節的,而現在是是倒過來了,確定乙個抽象類後,那些細節的實現得以抽象出來的方法為基準,變成了細節依賴於抽象了,不然你要繼承了乙個抽象類,你不完全實現它的方法的話可不讓你例項化物件的啊。

當兩個模組之間存在緊密的耦合關係時,最好的方法就是分離介面和實現:在依賴之間定義乙個抽象的介面,供高層模組呼叫,底層模組實現介面的定義,從而有效控制耦合關係,達到依賴於抽象的設計目的。

依賴於抽象就是不對實現程式設計,而對介面程式設計。依賴於抽象是乙個通用原則,而有些時候依賴於細節是在所難免的,我們需要根據具體情況在在抽象與具體之間進行取捨。

5.介面分離原則(inte***ce segregation principle,isp)

該原則的核心思想是:使用多個小的專門的介面,而不要使用乙個大的總介面。具體而言,介面應該是內聚的,應該避免「胖」介面。乙個類對另乙個類的依賴應該建立在最小的介面上,而不要強迫依賴不同的方法,這是一種介面汙染。

其實簡單點的講與前面說的單一職責類似,這裡的介面不是函式介面,而是乙個類。c#中的有專門的介面inte***ce,和類區分開來,而且c#中不像c++支援類的多繼承,只支援介面的多繼承,所以這裡可以把介面理解成功能更小更特殊的類,乙個介面可能就只要那麼幾個很少的方法就ok了。

介面分離手段主要有以下兩種方式:

(1)利用委託分離介面;

(2)利用多重繼承分離介面。

6.小結

概括地講,物件導向設計原則仍然是物件導向思想的體現。例如,

(1)單一職責原則要求類只負責一件事情。介面分離原則,讓客戶只關心他們所需的介面。單一職責原則與介面分離原都體現了內聚的思想;

(2)開放封閉原則,要求類不作修改而能夠擴充套件功能,體現了類的封裝與繼承;

(3)liskov替換原則,要求派生類要能夠替換基類,是對類繼承的規範;

(4)依賴倒置原則,要求類依賴於抽象,而不是實現,是抽象思想的體現。

上面五條物件導向設計原則,可以幫助我們設計出**易於復用、功能易於擴充套件、運營易於維護的程式,需要我們在實踐中遵守。

物件導向 五大原則

沒有規矩,不成方圓!物件導向亦是如此!五大原則讓物件導向技術更加規範,讓我們深入了解一下!就乙個類而言,應該僅有乙個引起它變化的原因。是盡量能讓類的變化減少,乙個類做好自己的本職工作就好了,別操太多的心,從而減少職責耦合!防止設計時產生一些不必要的問題!類的職責分離是我們在程式設計的時候,需要去考慮...

物件導向五大原則

參考 物件導向五大原則 英文縮寫為solid s srp single responsibility principle 單一職責原則 o ocp open close principle 開放關閉原則 l lsp liskov substitution principle 李氏替換原則 i isp...

物件導向設計的五大原則

筆試題 物件導向設計的五大原則?你的設計違背了哪一條,結合開發經驗。去凱蘭高面試時,讓做的筆試捲裡的一道題,當時覺得完全沒聽過,現在記錄一下,保不准什麼時候又被問到。在物件導向設計中,如何通過很小的設計改變就可以應對設計需求的變化,這是令設計者極為關注的問題。為此不少oo先驅提出了很多有關物件導向的...