Blog
0

Open-Closed Principle

  • Pradyumn Sharma
  • July 25, 2017

Tags:

When you need to modify a class to change its behaviour, refactor it in such a manner that you don’t need to modify it again for the same reason.

The Open-Closed Principle (OCP) is the second of the five SOLID principles of object-oriented design. It states that:

Software entities (classes, modules, functions, etc) should be open for extension, but closed for modification.

What does this mean?

SOLID is an acronym for five important principles of object-oriented design:

  • Single Responsibility Principle (SRP)
  • Open-Closed Principle (OCP)
  • Liskov Substitution Principle (LSP)
  • Interface Segregation Principle (ISP)
  • Dependency Inversion Principle (DIP)

A full list of Robert Martin’s principles is available at: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

Let us first talk about classes. We know that, from time to time, as the requirements for a system change, we need to modify the code in one or more classes of the system.

The OCP suggests that we should be able to extend the behaviour of a class, without having to modify its code. How is that possible?

Let’s take an example: suppose we have a class called ‘BankLoan, which represents the behaviour of, and information about, a loan from a bank. One of its public methods is: getInterestForMonth:

1
2
3
public float getInterestForMonth () {
    return principal * interestRate / 12;
}

[Typically, there is another public method called getInterestForPartMonth (Date startDate, Date endDate), which is used only in the first and the last months of a loan, for computing the interest for the partial month. But we can ignore that method, at least for the time being.]


Simple stuff. The code has been tested, delivered to the customer, and put into production.

Now, some time later, our customer tells us that while for the long-term loans, the bank will continue to calculate interest for a month as above (1/12th of the annual interest amount), for short-term loans, say, for tenure of less than or equal to 91 days, they have decided to compute the interest based on the actual number of days in the month. So, for example, since March has more days than April, the interest charged to a borrower in the month of March will be proportionately more than the one in April.

This suddenly complicates things. What about February and leap years? In a leap year, February has 29 days out of 366 for the year, while in other years, it has 28 days out of 365. Our customer tells us that we have to account for leap years correctly. Thus, the interest that a borrower will pay for:

  • January in a leap year will be 31/366 of the full year’s interest
  • January in a non-leap year will be 31/365 of the full year’s interest
  • February in a leap year will be 29/366 of the full year’s interest
  • February in a non-leap year will be 28/365 of the full year’s interest

It turns out, that these are just some of the ways in which banks compute interest. There are other ways too.

  • Our current, simple implementation (1/12th of the annual interest for a month) is known as 30/360 in banking parlance.
  • The proposed, new requirement is known as actual/actual
  • And there are others, such as actual/365 fixed, in which the extra day of a leap year is ignored

(For a more detailed description of the above, and other methods of interest computation, please refer to this Wikipedia article.)

To summarize, our customer asks us to retain the 30/360 approach for long-term loans (more than 91 days), and actual/actual approach for short-term loans (less than or equal to 91 days).

We now realize that we must change the signature of the getInterestForMonth method. It will need to know the month and year for which the computation is to be done. Apart from this, the implementation will also depend on the tenure of the loan.

So a modification to the BankLoan class is inevitable. But can we use this as an opportunity to refactor the code in such a manner that if in the future, the bank asks us to incorporate some other interest computation approaches, such as actual/365 fixed, we would not have to modify the BankLoan class any further.

Essentially, what we need to do is to extract the variant part of the class (interest computation approach) away from it. One way to achieve this would be to have a separate class hierarchy, with a common interface, as shown in the diagram below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class BankLoan {
    // …
    private float principal;
    private float interestRate;
    private int tenureInDays;
    private InterestStrategy interestStrategy;
    // …
    public float getInterestForMonth (int year, int month) {
        return interestStrategy.getInterestForMonth (this, year, month);
    }
    // …
}
 
interface InterestStrategy {
    public float getInterestForMonth (BankLoan loan, int year, int month);
    // …
}
 
class ThirtyByThreeSixtyInterestStrategy implements InterestStrategy {
    public float getInterestForMonth (BankLoan loan, int year, int month) {
        // …
    }
}
 
class ActualByActualInterestStrategy implements InterestStrategy {
    public float getInterestForMonth (BankLoan loan, int year, int month) {
        // …
    }
}

This refactoring may have been quite some work, and many client classes may have to be modified for this. But those would have had to be modified even if we had chosen not to separate the variant part from the BankLoan class.

But now, because of this update, our BankLoan class would no longer have to be modified if in the future, our customer asks us to add another interest computation approach, such as actual/365 fixed.

The BankLoan class is now open for extending its behaviour, while being closed for modification.

Closing Remarks

Applying the Open-Closed Principle makes it easier to subsequently extend the behavior of a class without having to modify its source code. The key to achieving this is to have a separate class hierarchy with an interface, in which we extract the variant behaviour(s) of the original class.

Of course, it would also have been possible to make BankLoan an abstract class, with getInterestForMonth as an abstract method, and have separate subclasses for each of the different interest computation strategies. But as we’ll see in another article later, using delegation to a class through an interface (as in our implementation) is usually a better approach than having subclasses.

We can see the OCP approach in many of the GoF design patterns, such as Strategy, State, Abstract Factory, and Bridge. All these patterns use delegation to another class through an interface.

However, two of the GoF design patterns — Template Method and Factory Method, can be seen to use the OCP approach using concrete subclasses for extracting variant behaviour from an abstract superclass.

Though the example presented in this article applies OCP to a class, we can similarly apply the OCP to other types of software entities, such as components.


21 responses to “Open-Closed Principle”

  1. Himalaya Herbals 【臉部保養】茉莉清爽化妝水的商品介紹 Himalaya Herbals,臉部保養,茉莉清爽化妝水

  2. acseine 【臉部保養系列】ミルキィ クレンズアップ的商品介紹 acseine,臉部保養系列,ミルキィ クレンズアップ

  3. I have learn a few good stuff here. Definitely worth bookmarking for revisiting. I wonder how a lot attempt you place to create the sort of fantastic informative website.

  4. You enter actuality a good webmaster. The internet site launching velocity can be unbelievable. It appears that you are carrying out every one of a kind key. Likewise, The particular belongings usually are work of art.. youtube terbaru you will have completed fantastic employment during this topic!

  5. Derma Veil ® 被喻為新世代逆齡完美輪廓塑造,最新一代的PLLA膠原。 2003年獲得Mexican Ministry of Health (SSA)認證及美國FDA出口認證,並於2006年在拉丁美洲及遠東至東南亞地區廣泛使用,多個臨床實例見證能改善老化、遺傳、疾病(如脂肪萎縮)等引起的凹陷問題,其效果備受認同。蘊含兩大活性成分均具有生物兼容性及分解性,可逐步被人體自然分解吸收,有效塑造童顏肌 : 1. 聚左乳酸 (Poly-L-lactic acid / PLLA) : 促進骨膠原生長 2. 甘醇酸(Glycolic Acid ) 使皮膚表皮層黏膠性脂質鬆軟,改善皮膚厚度,加速細胞再生,減少皺紋及疤痕,加強保濕功能,增加光澤,美白效果。 由於甘醇酸分子較小,容易滲透皮膚 治療前: 皮膚的凹陷/皺紋 治療後: 成分被人體吸收、並刺激膠原增生,撫平皺紋及凹陷部位。 注入BOTOX(保妥適)會抑制突觸前膜釋放神經遞質,阻斷乙酰膽鹼(Acetylcholine)的釋放,從而使肌肉張力下降或癱瘓麻痺,皺紋也隨之而逐漸消失。

  6. ORION是一部擁有三重長脈衝 755nm/1064nm/532nm的激光儀,提供專業和最新的技術,強調其穩定性和便利性的能力。另外,最佳的參數是基於各種臨床結果提供的。三長脈衝激光系統 -Long pulsed Nd:YAG (1064nm) -Long pulsed Alexandrite (755nm) -Long Pulsed KTP (532nm) 先進技術 – 氣冷卻系統(ACD) – 智能面板 – 三波長 – 高電源 應用 -Long pulsed Nd:YAG (1064nm)●脫毛●嫩膚●血管病變●腿部靜脈曲張●痤瘡●灰指甲●疣-Long pulsed Alexandrite (755nm)●脫毛●美白肌膚●色素性病變●黑頭●黃褐斑●疤-Long Pulsed KTP (532nm)●血管病變●酒渣鼻●色素性病變●太陽雀斑●美白肌膚●鮮紅斑痣●血管瘤

  7. 我們採用國際及美國食品及藥物管理局FDA認可的CO2 激光儀 LUTRONICS® SPECTRA SPR, 具安全性, 準確度高 . 二氧化碳激光可安全地去除皮膚上的癦痣、肉粒、疣、老人斑等問題。此激光的幼細光束可準確及直接地將要去除的組織氧化,過程快捷,傷口細小及乾淨,對周圍的皮膚傷害減至最少。一般1-2次就可永久去除。

  8. Venus Legacy™是第一個,也是唯一一個得到美國食品藥品監督管理局批准,利用4D™技術結合多極射頻(RF)、磁力脈衝、變量脈衝VariPulse™技術(VP)和實時熱力反饋的設備,這使Venus Legacy™能夠提供一個既安全又無痛的療程,並取得理想效果。Venus Legacy™的療程為所有類型的肌膚提供一個100安全和無痛的美容過程,並針對面部、頸部及身體各處,提供以下即時和持久的效果 非手術塑型 減少橙皮紋 減少皺紋 減少皮下脂肪 收緊肌膚

  9. Venus Viva™對所有皮膚類型都是安全的,並使用革命性的Nano Fractional Radio Frequency™(納米點陣射頻™)和Smart Scan™(智能掃描™)技術,通過選擇性真皮加熱,從而提供優異的治療效果。使用Nano Fractional RF™將能量透過表皮傳遞至真皮,從而產生熱量,並啟動膚膚的生理機制,重建膠原蛋白及刺激纖維母細胞,最終刺激導致組織重塑。功效:✔改善膚質✔肌膚緊緻✔減淡妊娠紋✔痤瘡及暗瘡疤痕✔減淡細紋及皺紋✔面部肌膚賦活再生 適合面部及頸部

  10. SMAZ換能器傳送更穩定,更安全,更有效,和疼痛更少的HIFU能量。 SMAZ不需要應用較高的能量便可到達浅肌肉腱膜層。主要治療:-抬頭紋 -眉間紋 -鼻樑紋 -魚尾紋 -法令紋 -淚溝 -木偶紋 -垂直唇紋 -嘴角紋 -頸紋

  11. NEAUVIA,歐洲血統透明質酸,目前遍布於全世界56個國家,行政總部在瑞士,卻是源自於意大利的品牌。採用21世紀先進的技術,提取出前所未有的高純度透明質酸,迅速的在全球攻占市場,卓越的品質,領先的技術和平民的價位,已經逐漸的出現在大眾的視線裡,被越來越的人使用。NEAUVIA以系列分女性專用和男性專用,大中小分子以及唇部專用和私處專用,其中私處專用己經在國內一些比較大的整形機構普遍使用。素材提取無與倫比的純淨,運用嶄新PEG鏈結技術-更安全

  12. 滿足客戶 says:

    Photoshop 教學導覽

  13. 我們彩用國際及美國食品及藥物管理局FDA認可的CO2 激光儀 Lutronics® Spectra SPR, 具安全性, 準確度高 . 二氧化碳激光可安全地去除皮膚上的癦痣、肉粒、疣、老人斑等問題。此激光的幼細光束可準確及直接地將要去除的組織氧化,過程快捷,傷口細小及乾淨,對周圍的皮膚傷害減至最少。一般1-2次就可永久去除。

  14. TULIP HIFU療程屬非侵入性及非手術的緊膚修身治療,獲歐盟CE、韓國KFDA、GMP、ISO9001、ISO13485等認證,安全可靠。 Tulip的DUAL HIFU精細技術,對面部和眼部治療特別有效;另外,TULIP FB有的13mm及7mm STAMP蓋印式治HIFU治療頭設計,眼、面以外部位,同時具「造身」效果。TULIP【DUAL HIFU高能量聚焦超聲波平台】【特點】- 非手術、非侵入性緊膚治療- 適用於任何膚色肌膚- 治療更精確、更安全- 備有7mm及13mm治療頭,可收緊腹部、臀部、手臂等鬆弛肌膚 【治療目的】- 緊緻肌膚- 提升輪廓- 減淡皺紋- 重塑輪廓線條- 嫩膚亮肌- 提升下垂眼部- 重塑身體線條 (用於7mm/13mm修身治療頭)- 重點減少脂肪細胞 (用於7mm/13mm修身治療頭)

  15. 付款方法 says:

    擴充套件多樣化

  16. 以低能量的1064-Q激光反覆掃於皮膚表面,逐步改善皮膚色素問題。 治療時產生的熱能能促進膠原蛋白的再生,回復肌膚彈性。 使用7mm平行光光頭,使輸出的激光更溫和及均勻。功效: 去除紋身 美白及去除面毛 令整體膚色更白更均勻 減淡及去除荷爾蒙斑或反黑 增加皮膚膠原蛋白,改善皮膚彈性 減淡深層色斑 : 黃褐斑,荷爾蒙斑,蝴蝶斑 以低能量的1064-QS激光反覆掃於皮膚表面,逐步改善皮膚色素問題 使用8-10mm平行光光頭,使輸出的激光 更溫和及均勻 1. 激光能透進皮膚深層 2. 激光被黑色素吸收 3. 產生熱能將黑色素體分解 4. 被呑噬細胞吸收及排出體外

  17. 注射 says:

    Venus Viva™對所有皮膚類型都是安全的,並使用革命性的Nano Fractional Radio Frequency™(納米點陣射頻™)和Smart Scan™(智能掃描™)技術,通過選擇性真皮加熱,從而提供優異的治療效果。使用Nano Fractional RF™將能量透過表皮傳遞至真皮,從而產生熱量,並啟動膚膚的生理機制,重建膠原蛋白及刺激纖維母細胞,最終刺激導致組織重塑。功效:✔改善膚質✔肌膚緊緻✔減淡妊娠紋✔痤瘡及暗瘡疤痕✔減淡細紋及皺紋✔面部肌膚賦活再生 適合面部及頸部

  18. 教主 says:

    當蛋白線埋入皮膚後,皮下組織會將蛋白線視為異物,啟動異物反應,因此刺激膠原蛋白生長,且可促進新陳代謝,更新老化肌膚,所以客戶在術後也會發覺膚質變得較透亮白皙。膠原蛋白提拉線像一個“磁力線”一樣,將埋入處附近的肌肉和脂肪固定在原處,不會往下墜,其後會吸引皮下組織往蛋白線集中部位移動,就會逐漸產生提拉的緊實效果。也被用於填充美容的微整形,蛋白線材就好比蓋房子的鋼骨支架,先埋入皮膚當作基底結構,然後再注入好比水泥的玻尿酸或自體脂肪,因為有吸附力不易擴散,就可穩定固定住填充物,讓立體支撐力效果更好。

  19. 過敏 says:

    Ion Magnum 是一種最新的減脂儀器,可以快速燃燒掉你身體的脂肪 , 讓你不需要做大量的體育鍛煉 , 輕鬆方便的達到專業美體的效果。 效果: 通過將你體內的脂肪轉化成肌肉,輕鬆减掉你的體重和腰圍。25分鐘的理療比健身房幾個小時的運動效果還要好! 副作用/風險: 該設備已在美國食品藥品監督管理局注册,注册分類爲醫療器械I類,I類醫療器械就是指普通人使用安全性非常好且沒有任何風險的器械。 减脂過程: 减脂板會直接固定安放於你身體的目標减肥部位,通過特殊的信號,Ion Magnum會將該部位的脂肪燃燒轉化成肌肉。(注意:該設備與你在其他沙龍中瞭解的肌肉轉化設備是完全不同的。)療程: 要想取得而保持完美的效果,一個療程需要進行10次理療,每3-7天進行一次。維持理療可以每兩周進行一次。

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2017 Pragati Software Pvt. Ltd. All Rights Reserved.

Enquiry