高質量程式設計的金玉良言 開放 封閉原則

2021-07-04 23:20:52 字數 1374 閱讀 2701

什麼是「開放-封閉」原則?

軟體的類、模組、函式等交付後,如果需要增加功能,不要去修改原來的**,而是通過新增加類的方法去擴充套件功能。

所謂的「開放」就是指開放介面,也就是通過增加子類的方法來增加功能;

「封閉」指的是封閉修改,也就是**一旦提交,就不要再去修改它。

總而言之,「開放-封閉」原則的意思就是:在我們設計乙個類的時候要盡量把這個類的功能考慮全面,然後一旦寫好了交付給第三方使用之後就不要再去修改。如果確實需要給乙個類增加功能,我們增加乙個含有新功能的類,原來的**不要動它。

但是,在實際開發中,「封閉」是相對的,乙個類寫完後並不能確保它未來永遠都不會被修改。因此,在設計類的時候,應該要「猜」這個類未來會作哪些擴充套件,然後把這些擴充套件抽象出乙個公共父類,父類中有這些子類都會執行的函式,只不過不同的子類函式實現不一樣;這樣,增加新功能時只要新建乙個類,繼承父類,覆蓋父類中的函式,然後客戶端需要使用新功能時,只要將新的子類物件賦給父類引用,再通過父類引用呼叫函式即可。

何時應對變化?

我們在設計或開發類的時候如果沒有將未來可能擴充套件的功能考慮到,這沒關係,只要在開發或新增需求的時候,一旦發現需要擴充套件功能並且需要修改原來**,我們就立刻給這個類抽象出父類,讓原本的功能和新增的功能都繼承這個父類。

比如,我們一開始拿到需求是這樣的:

開發乙個軟體,營業員只要輸入原價,就能根據「滿100返50」計算出折扣以後的價錢。

我們只需要建立乙個折扣類,該類裡面有乙個打折函式,這個函式需要輸入原價,然後它會按照「滿100返50」的規則計算出折後價。

過了一陣子後,超市的需求改了:

由於超市隔三差五就要辦**活動,但每次**活動的方式不一樣,所以需要開發乙個軟體,營業員只要輸入原價再選擇活動型別後,就能計算出折扣以後的價錢。

此時我們發現,折扣的形式有多種多樣,而現在我們的折扣類中只提供了「滿100返50」的打折方式,如果要增加其他打折方式就要往折扣類裡面增加新的打折方式,如果過了一陣子又要增加打折方式,就又要在折扣類裡面增加**,這就違背了「封閉修改」的原則。

正確的做法是,當我們發現需要增加打折功能的時候,我們將抽象出乙個打折類,這個類中有乙個抽象函式:discount(),然後讓各種不同的打折方式類繼承這個類,並重寫各自的打折方式。類這樣設計之後,當超市又要增加新的打折方式的時候,我們只需要建立乙個新的打折類,去繼承打折父類,並重寫打折函式;然後客戶端就可以呼叫這個新的功能了。

關於程式設計時的高質量

劍指offer 的第三張開始講關於高質量 的內容,裡面涉及到了關於程式設計時的邊界條件,細節疏忽的問題,這裡記錄一下 關於異常的處理有三種方法 1 返回值 利用函式的返回值,判斷是否出現問題,在windows下面,一般返回零表示成功,返回非零值,根據不同的值,代表不同的問題 2 全域性變數 當發生錯...

高質量的c程式設計之四

現在時間好緊張,只有週日有時間寫博了,周五下午去巨集福那邊助教,內容是關於分割單個檔案為多個檔案的專案,其中就有關於標頭檔案的使用,畢竟是大一的新生,問題很簡單乙個原來在乙個檔案中的部分內容分割出來,其中有乙個結構體的定義,標頭檔案a 乙個關於鍊錶的通用操作 用到了結構體定義 包含檔案 標頭檔案b,...

再談高質量c 程式設計的例題

今天在網上看到一道求助的題目,是關於指標作為函式引數的問題,讓我不由得再次想到了高質量c 程式設計的例題,這個題目在國內應該是相當有知名度,很多應聘的時候似乎都會看到它的身影,題目如下 void getmemory char p void test void 請問執行 test 函式會有什麼樣的結果...