1、定義
之前我們已經(jīng)說過:
集齊五個(gè)原則,就可以召喚神龍了。
神龍就是開放封閉原則公浪,可以這樣說:它是其他五大原則的實(shí)現(xiàn)昨悼,是面向?qū)ο笤O(shè)計(jì)的終極目標(biāo)捉腥。
既然開放封閉原則這么高端大氣上凳次歼捐,那我們趕緊來看一下開放封閉原則的定義何陆。
一個(gè)軟件實(shí)體應(yīng)當(dāng)對(duì)擴(kuò)展開放,但對(duì)修改關(guān)閉豹储。
對(duì)擴(kuò)展開放的意思是贷盲,我們可以肆無忌憚的增加新功能。
對(duì)修改關(guān)閉的意思是剥扣,對(duì)原有功能不會(huì)產(chǎn)生任何修改巩剖。
可以說這是寫代碼的最高境界。
遺憾的是钠怯,這種情況不可能發(fā)生佳魔。需求本身就是在修修改改,程序又是為需求服務(wù)的晦炊,代碼不修改是不可能的鞠鲜。
我們要盡量做到的開放封閉原則。完全做到開放封閉原則断国,臣妾做不到哇贤姆!
2、怎么做
大家可以思考下:怎么樣才能做到對(duì)擴(kuò)展開放稳衬,對(duì)修改封閉呢霞捡?
方法1:抽象一個(gè)接口或者抽象類,定義公共的方法薄疚,從而方便擴(kuò)展碧信。
方法2:引用接口或者抽象類,不依賴具體實(shí)現(xiàn)類街夭。
方法3:接口和抽象類不能修改砰碴,可以繼承接口或者抽象類從而達(dá)到擴(kuò)展的目的。
這三個(gè)方法都在圍繞著一個(gè)核心莱坎,是什么呢衣式?
沒錯(cuò),就是抽象檐什。
我們應(yīng)該面向抽象編程碴卧,不要面向具體編程。
有沒有似曾相識(shí)的感覺乃正?
是的住册,依賴倒置原則中也曾經(jīng)提到過這樣的思想。
開放封閉原則是總綱瓮具,而依賴倒置原則是開放封閉原則一個(gè)非常好的實(shí)現(xiàn)荧飞。
還有里氏替換原則也是對(duì)開放封閉原則的一種非常良好的實(shí)現(xiàn)凡人,所以我們可以直接用《嘻哈說:里氏替換原則》中的場(chǎng)景以及代碼。
3叹阔、場(chǎng)景
八大菜系的廚師
番茄餐廳挠轴,經(jīng)過兢兢業(yè)業(yè)的經(jīng)營(yíng),從一家小型的餐館成長(zhǎng)為一家大型餐廳耳幢。
廚師:老板岸晦,咱們現(xiàn)在家大業(yè)大客流量也大,雖然我精力充沛睛藻,但我也架不住這么多人的摧殘启上。
老板:摧殘?你確定店印?
廚師:哪能冈在,您聽錯(cuò)了,是照顧按摘,架不住這么多人的照顧包券。
老板:小火雞,可以呀院峡,求生欲很強(qiáng)嘛兴使。那你有什么想法?
廚師:我覺得咱們可以引入八大菜系廚師照激,一來,什么菜系的菜就交給什么菜系的廚師盹牧,味道質(zhì)量會(huì)更加的上乘俩垃,才能配的上我們這么高規(guī)格的餐廳。
老板:嗯汰寓,說的有點(diǎn)道理口柳,繼續(xù)說。
廚師:二來有滑,人手多了跃闹,還可以增加上菜的速度,三來......
老板:有道理毛好,馬上招聘廚師望艺,小火雞,恭喜你肌访,升官了找默,你就是未來的廚師長(zhǎng)。因?yàn)槟闱笊娴暮軓?qiáng)吼驶。
廚師長(zhǎng):謝謝老板惩激。(內(nèi)心:我求生欲很強(qiáng)店煞?哪里強(qiáng)了?放學(xué)你別走风钻,我讓你嘗嘗我的厲害顷蟀,給你做一桌子好菜)
求生欲果真很強(qiáng)。
4骡技、實(shí)現(xiàn)
package com.fanqiekt.principle.liskov;
/**
* 抽象廚師類
*
* @author 番茄課堂-懶人
*/
public abstract class Chef {
/**
* 做飯
* @param dishName 餐名
*/
public void cook(String dishName){
System.out.println("開始烹飪:"+dishName);
cooking(dishName);
System.out.println(dishName + "出鍋");
}
/**
* 開始做飯
*/
protected abstract void cooking(String dishName);
}
抽象廚師類鸣个,公有cook方法,負(fù)責(zé)廚師做飯的一些相同邏輯哮兰,例如開始烹飪的準(zhǔn)備工作毛萌,以及出鍋。
具體做飯的細(xì)節(jié)則提供一個(gè)抽象方法cooking(正在做飯)喝滞,具體菜系廚師需要重寫該方法阁将。
package com.fanqiekt.principle.liskov;
/**
* 山東廚師
*
* @author 番茄課堂-懶人
*/
public class ShanDongChef extends Chef{
@Override
protected void cooking(String dishName) {
switch (dishName){
case "西紅柿炒雞蛋":
cookingTomato();
break;
default:
throw new IllegalArgumentException("未知餐品");
}
}
/**
* 炒西紅柿雞蛋
*/
private void cookingTomato() {
System.out.println("先炒雞蛋");
System.out.println("再炒西紅柿");
System.out.println("...");
}
}
魯菜廚師ShanDongChef繼承了廚師抽象類Chef,實(shí)現(xiàn)了抽象方法cooking右遭。
新增西紅柿炒雞蛋的功能做盅,我們可以通過繼承Chef抽象類實(shí)現(xiàn)ShanDongChef類進(jìn)行擴(kuò)展,這就是對(duì)擴(kuò)展開放窘哈。
避免修改Chef類吹榴,從而避免修改給原有系統(tǒng)帶來新的問題,這就是對(duì)修改封閉滚婉。
5图筹、嘻哈說
接下來,請(qǐng)您欣賞懶人為開放封閉原則創(chuàng)作的歌曲让腹。
嘻哈說:接口隔離原則
作曲:懶人
作詞:懶人
Rapper:懶人
對(duì)擴(kuò)展開放
對(duì)修改封閉
對(duì)具體來講
要大膽痛擊
對(duì)抽象愛上
編程就會(huì)容易
開放封閉我中意瘋迷
做番茄雞蛋可以新增山東大廚
而不是在廚師類里大修大補(bǔ)
否則代碼就像狂風(fēng)中的蠟燭
隨時(shí)可能一命嗚呼
閑來無事聽聽曲远剩,知識(shí)已填腦中去;
學(xué)習(xí)復(fù)習(xí)新方式骇窍,頭戴耳機(jī)不小覷瓜晤。
番茄課堂,學(xué)習(xí)也要酷腹纳。