1. 程式人生 > >面向對象原則之一 開放封閉原則(開閉原則)

面向對象原則之一 開放封閉原則(開閉原則)

text uml類圖 一個 cnblogs 面向對象 技術 只有一個 cor pan

原文:面向對象原則之一 開放封閉原則(開閉原則)

前言

面向對象有人分為五大原則,分別為單一職責原則、開放封閉原則、依賴倒置原則、接口隔離原則、裏氏替換原則。

也有人分為六大原則,分別為單一職責原則、開放封閉原則、依賴倒置原則、接口隔離原則、裏氏替換原則、迪米特法則。

現在我們來介紹開放封閉原則,也叫開閉原則

開閉原則

1)概念

官方說法是 軟件實體(模塊、類、函數等)應該可以擴展,但是不可以修改。也就是說軟件對擴展開放,對修改關閉。

需要說明的是,對修改關閉不是說軟件設計不能做修改,只是盡量不要做不必要的修改。怎麽才能做到呢?那就是有相應的擴展性。

其實,軟件有相應的擴展性是好處,但是不能說每個地方都有擴展。反而造成了代碼的臃腫。所以這裏的擴展與修改關閉是有限制的。

開閉原則,可以說是其他五大原則的實現,也是面向對象設計的終極目標。我們也可以說成開閉原則是其他原則的核心。

說了這些概念性的東西,似懂非懂。我們可以試試從下面的例子來看看是否更加上心。

2)深入理解

開閉原則怎麽能更深入的理解呢?還是說說我們身邊的例子吧。

比如我們平常喝水用的一次性紙杯。平常人只是用來裝水。喝完水就扔了。這就是這個紙杯的生命周期。紙杯這一生只完成了它的一個功能:裝水。紙杯此時就很封閉了,沒有什麽擴展性。

此時,我看到身邊有一支花苗,我想要拿回家種。但是沒有容器呀? 啊?旁邊不是有一個紙杯嗎,可以用此紙杯來種這朵花苗。

紙杯有了它的另外一個擴展性,就是種花苗。

紙杯不僅有裝水、種花苗的用途,以後還可以有裝小垃圾、沖茶、回收等功能。對於以後這些功能,我們要想到他們的擴張性。

在紙杯只有一個裝水的功能的時候,我們只寫一個紙杯功能類,說紙杯能裝水。但是以後有擴展呢?這一方面我們要預先判斷。預先判斷它以後可能會根據需求的變動而擴展。對於紙杯本來的裝水功能,不能說不能修改,此功能只能在此函數、類中修改。這就是開閉原則的核心。

所以,紙杯在開閉原則所體現的是:盡量少修改,未來可能擴展的模塊、類做好預算的判斷。如果要修改,只能在此函數此類修改,不能牽涉到其他地方。

下面,我們用UML類圖來直觀地說明一下紙杯的設計吧。

當紙杯只有一個功能,裝水時。有一個紙杯操作接口,有一個紙杯操作實現類。

技術分享圖片

當我們要添加一個功能 種花苗時,我們不也是加一個方法嗎?如下:

技術分享圖片

當添加N個方法時,不也是在紙杯的操作接口上面添加N個方法嗎?

我們想一想,此時已經背離了我們的開閉原則。因為每添加一個方法,都要在操作類上面做修改。所以,我們按照開閉原則,開做了以下合理的設計:

技術分享圖片

從上面可以看出,我們把紙杯的操作類,統一寫成一個接口,每個不同的操作繼承此接口來完成各自操作。我們還開到多了一個類,叫客戶端類,其實此類也不難理解。也就是要最終操作紙杯的類。

3)其他例子

開閉原則其實在大話設計模式中說得非常好,讓人通俗易懂。

它舉了一個例子,我覺得說得非常好。是加減乘除法的例子。

開始需求是做一個加法的操作。後來繼續加入減法、乘法、除法。

開始我們想加法以後可能會做一個需求變更:加入其它的算法法則。所以我們要有一個預判性,這個預判性會導致我們項目以後的擴展性,也會導致如果需求發生變更,程序修改的難易程度。

所以,我們要做一個算法法則的操作類,加減乘除法都繼承此操作接口。再加一個算法法則的客戶端類類操作此算法。

我們來上一下大話設計模式中的圖:

技術分享圖片

4)總結

開閉原則是我們面向對象設計的目標,我們靈活地運用好此目標也不是易事。所以開閉原則要深入的理解,才能做好面向對象的編程,才能做一個好的軟件。

其他鏈接:

開放封閉原則(開閉原則)

單一職責原則

依賴倒置原則

接口隔離原則

裏氏替換原則

迪米特法則

此文轉發,請註明出處,謝謝。

可以關註本人的公眾號,多年經驗的原創文章共享給大家。

技術分享圖片

面向對象原則之一 開放封閉原則(開閉原則)