首頁  >  文章  >  後端開發  >  C#中物件導向設計七個原則介紹

C#中物件導向設計七個原則介紹

巴扎黑
巴扎黑原創
2017-09-06 11:21:042170瀏覽

C#中物件導向設計七個原則介紹

#

一:單一職責原則(Single Responsibility Principle, SRP)

    1、定義:一個物件應該只包含單一的職責,並且該職責被完整地封裝在一個類別中

     或:就一個類別而言,應該只有一個造成它變化的原因。

   2、分析:一個類別(或大到模組,小到方法)承擔的職責越多,它被重複使用的可能性越小,如果一個類別承擔的職責過多,就相當於將這些職責耦合在一起,當其中一個職責變化時,可能會影響其他職責的運作。 類別的職責主要包括兩個面向:資料職責和行為職責,資料職責透過其屬性來體現,而行為職責則透過其方法來體現。 單一職責原則是實現高內聚、低耦合的指導方針,在許多程式碼重構手法中都能找到它的存在,它是最簡單但又最難運用的原則,需要設計人員發現類別的不同職責並將其分離,而發現類別的多重職責需要設計人員具有較強的分析設計能力和相關重構經驗。

   3、實例:

實例說明某基於Java的C/S系統的「登入功能」透過以下登入類別(Login)實現:
現使用單一職責原則對其進行重構。

二:開閉原則(Open-Closed Principle, OCP)

     1、定義:一個軟體實體應對擴充開放,對修改關閉。也就是說在設計一個模組的時候,應當使這個模組可以在不被修改的前提下被擴展,也就是實現在不修改原始碼的情況下改變這個模組的行為。  

   2、分析:開閉原則由Bertrand Meyer於1988年提出,它是物件導向設計中最重要的原則之一。在開閉原則的定義中,軟體實體可以指一個軟體模組、一個由多個類別組成的局部結構或一個獨立的類別。抽象化是開閉原則的關鍵。 開閉原則也可以透過一個更具體的「對可變性封裝原則」來描述,對可變性封裝原則(Principle of Encapsulation of Variation, EVP)要求找到系統的可變因素並將其封裝起來。

三:里氏代換原則(Liskov Substitution Principle, LSP)      

1、定義:如果對每一個類型為S的物件o1,都有類型為T的物件o2,使得以T定義的所有程式P在所有的物件o1都代換成o2時,程式P的行為沒有變化,那麼型別S是型別T的子型別

  或:所有參考基底類別(父類別)的地方必須能透明地使用其子類別的物件。

2、分析:里氏代換原則由2008年圖靈獎得主、美國第一位電腦科學女博士、麻省理工學院教授Barbara Liskov和卡內基.梅隆大學Jeannette Wing教授於1994年提出。

里氏代換原則可以通俗表述為:在軟體中如果能夠使用基類對象,那麼一定能夠使用其子類對象。把基類都替換成它的子類,程式將不會產生任何錯誤和異常,反過來則不成立,如果一個軟體實體使用的是一個子類的話,那麼它不一定能夠使用基類。里氏代換原則是實現開閉原則的重要方式之一,由於使用基類對象的地方都可以使用子類對象,因此在程序中盡量使用基類類型來對對象進行定義,而在運行時再確定其子類別類型,並用子類別物件來取代父類別物件。

四:依賴倒轉原則(Dependence Inversion Principle, DIP)    

1、定義:高層模組不應該依賴低層模組,它們都應該依賴抽象。抽像不應該依賴細節,細節應該依賴抽象

  或:要針對介面編程,不要針對實作程式設計。 (Program to an interface, not an implementation.)   

2、分析:依賴倒轉原則是Robert C. Martin在1996年為《C++ Reporter》所寫的專欄Engineering Notebook的第三篇,後來加入到他在2002年出版的經典著作《Agile Software Development, Principles, Patterns, and Practices》。   

     簡單來說,依賴倒轉原則就是指:程式碼要依賴抽象的類,而不要依賴特定的類別;要針對介面或抽象類別編程,而不是針對特定類別編程。 實現開閉原則的關鍵是抽象化,並且從抽象化導出具體化實現,如果說開閉原則是面向對象設計的目標的話,那麼依賴倒轉原則就是物件導向設計的主要手段。

   依賴倒轉原則的常用實作方式之一是在程式碼中使用抽象類,而將特定類別放在設定檔中。

類別之間的耦合 

零耦合關係

具體耦合關係

抽象耦合關係

依賴倒轉原則要求客戶端依賴抽象耦合,以抽象方式耦合是依賴倒轉原則的關鍵。

依賴注入 

#建構注入(Constructor Injection):透過建構子注入實例變數。 

設值注入(Setter Injection):透過Setter方法注入實例變數。 

介面注入(Interface Injection):透過介面方法注入實例變數。

五:介面隔離原則(Interface Segregation Principle, ISP)

   1、定義:客戶端不應該依賴那些它不需要的介面   注意,在該定義中的介面指的是所定義的方法。

   或:一旦一個介面太大,則需要將它分割成一些更細小的接口,使用該接口的客戶端僅需知道與之相關的方法即可。

   2、分析:介面隔離原則是指使用多個專門的接口,而不使用單一的總接口。每個介面應該承擔一種相對獨立的角色,不多不少,不干不該幹的事,該幹的事都要幹。

 (1) 一個接口就只代表一個角色,每個角色都有它特定的一個接口,此時這個原則可以叫做「角色隔離原則」。

   (2) 介面僅提供客戶端所需的行為,即所需的方法,客戶端不需要的行為則隱藏起來,應當為客戶端提供盡可能小的單獨的接口,而不要提供大的總接口。

        使用介面隔離原則分割介面時,首先必須滿足單一職責原則,將一組相關的操作定義在一個介面中,且在滿足高內聚的前提下,介面中的方法越少越好。 可以在進行系統設計時採用客製化服務的方式,即為不同的客戶端提供寬窄不同的接口,只提供使用者需要的行為,而隱藏使用者不需要的行為。

六:合成復用原則(Composite Reuse Principle, CRP)又稱為組合/聚合復用原則(Composition/ Aggregate Reuse Principle, CARP)

#     1、定義:盡量使用對象組合,而不是繼承來達到復用的目的。 (Favor composition of objects over inheritance as a reuse mechanism.)

     2、解析:合成復用原則是指在一個新的物件裡透過關聯關係(包括組合關係和聚合關係)來使用一些已有的對象,使之成為新對象的一部分;新對象透過委派調用已有對象的方法達到復用其已有功能的目的。簡言:要盡量使用組合/聚合關係,少用繼承。

在物件導向設計中,可以透過兩種基本方法在不同的環境中重複使用已有的設計和實現,即透過組合/聚合關係或透過繼承。
繼承復用:實作簡單,易於擴充。破壞系統的封裝性;從基底類別繼承而來的實作是靜態的,不可能在運行時發生改變,沒有足夠的靈活性;只能在有限的環境中使用。 (「白箱」復用 )

組合/聚合復用:耦合度相對較低,選擇性地呼叫成員物件的操作;可以在運行時動態進行。 (「黑箱」多用)
組合/聚合可以使系統更靈活,類別與類別之間的耦合度降低,一個類別的變化對其他類別造成的影響相對較少,因此一般首選使用組合/聚合來實現復用;其次才考慮繼承,在使用繼承時,需要嚴格遵循里氏代換原則,有效使用繼承會有助於對問題的理解,降低複雜度,而濫用繼承反而會增加系統構建和維護的難度以及系統的複雜度,因此需要慎重使用繼承復用。

七:迪米特法則(Law of Demeter, LoD)又稱為最少知識原則(Least Knowledge Principle, LKP)

1、定義:

#(1 ) 不要和「陌生人」說話。英文定義為:Don't talk to strangers.

(2) 只與你的直接朋友通信。英文定義為:Talk only to your immediate friends.

(3) 每一個軟體單位對其他的單位都只有最少的知識,而且局限於那些與本單位密切相關的軟體單位。英文定義為:Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.   

  2、分析:迪米特法則來自於1987年秋美國東北大學(Northeastern University )一個名為「Demeter」的研究計畫。簡單地說,迪米特法則就是指一個軟體實體應盡可能少的與其他實體發生交互作用。這樣,當一個模組修改時,就會盡量少的影響其他的模組,擴展會相對容易,這是對軟體實體之間通訊的限制,它要求限制軟體實體之間通訊的寬度和深度。

以上是C#中物件導向設計七個原則介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn