在所有關(guān)于軟件維護(hù)的故事中,功能的擴(kuò)展是一個(gè)永恒的話題。正因?yàn)檐浖到y(tǒng)需要功能的擴(kuò)展,需要新功能的加入,才使我們的編程需要那么多的設(shè)計(jì)??梢哉f,正是因?yàn)樾鹿δ艿臄U(kuò)展,使得原有的系統(tǒng)質(zhì)量下降;正是因?yàn)檐浖|(zhì)量的下降,才使我們需要進(jìn)行深入的分析與研究,制訂設(shè)計(jì)原則,總結(jié)設(shè)計(jì)模式;正是因?yàn)橐鉀Q軟件質(zhì)量下降的問題,經(jīng)過一番艱苦卓絕的摸索過程,我們才認(rèn)識到系統(tǒng)重構(gòu)才是解決該問題的最佳方案。
然而,事情總是這樣的,每個(gè)系統(tǒng)當(dāng)我們進(jìn)行初次的設(shè)計(jì)時(shí),設(shè)計(jì)思路、程序結(jié)構(gòu)總是比較完美的??墒钱?dāng)初次設(shè)計(jì)結(jié)束后,我們在日后的維護(hù)中,開始往系統(tǒng)里添加新功能時(shí),系統(tǒng)開始不完美了,甚至開始出現(xiàn)問題了,新增的功能總是或多或少有些水土不服。怎么辦呢?要保證每次需求的變更時(shí)軟件質(zhì)量不會(huì)下降,必須記住這樣一個(gè)原則:先重構(gòu)再添加新功能。
添加新功能前先重構(gòu)原有系統(tǒng),其目的有兩個(gè):
1. 軟件的設(shè)計(jì)總是與軟件的復(fù)雜程度有關(guān)的,原有的設(shè)計(jì)是在原有需求不復(fù)雜的條件下做出的,但隨著新功能的加入,軟件復(fù)雜度在發(fā)生著變化,因此必須要調(diào)整原有的設(shè)計(jì)以適應(yīng)新的需求;
2. 為了提高軟件的可維護(hù)性與易變更性,添加新功能應(yīng)遵循OCP原則。而要遵循OCP原則,我們應(yīng)當(dāng)在不添加新功能的前提下先進(jìn)行重構(gòu),設(shè)計(jì)出可擴(kuò)展點(diǎn)出來,然后再添加新功能。
是的,明白這兩點(diǎn)非常重要。軟件維護(hù)越來越困難,不是因?yàn)榭蛻籼岢隽诵枨笞兏?,而是因?yàn)槲覀儧]有隨著軟件復(fù)雜度的增加改變我們的軟件結(jié)構(gòu)。軟件需求起初比較簡單,是幾乎所有軟件的共性。但隨著軟件復(fù)雜度的增加,我們卻不敢有效地調(diào)整現(xiàn)有的軟件結(jié)構(gòu),以適應(yīng)新的需求,這就真正是我們的問題了。不敢調(diào)整,是害怕原有功能會(huì)出錯(cuò),但不調(diào)整,則意味著我們軟件設(shè)計(jì)的問題會(huì)越來越大,進(jìn)而越來越難于維護(hù)。改與不改,我們面臨著兩難的抉擇。
解決這個(gè)兩難的難題其實(shí)不難,實(shí)際上就是一層窗戶紙一桶就破了。試想,我們不敢修改原有代碼的真正原因是因?yàn)楹ε赂某鰡栴}影響原有功能的正常運(yùn)行。那么,我們找一個(gè)方法使我們在修改原有代碼時(shí)不會(huì)出現(xiàn)問題,換句話說是出現(xiàn)問題以后會(huì)及時(shí)發(fā)現(xiàn),則問題就可以解決,這個(gè)方法就是重構(gòu)與測試。
客戶判斷一個(gè)功能是否正常運(yùn)行的標(biāo)準(zhǔn),就是當(dāng)輸入一個(gè)值后,能得到客戶期望的結(jié)果,不管系統(tǒng)內(nèi)部是怎樣運(yùn)行的。因此,建立這樣一個(gè)測試用例,讓軟件系統(tǒng)在重構(gòu)前后都能通過這些測試用例,就可以保證重構(gòu)的正確性(關(guān)于如何建立,我們還會(huì)在后面仔細(xì)討論)。重構(gòu)以后,外部功能是一致的,但內(nèi)部程序結(jié)構(gòu)卻變得更加易于添加新的功能,使新的功能與原有系統(tǒng)可以有機(jī)地融為一體,這才是我們的目的。說起來比較抽象,我們來舉一個(gè)示例吧:
在許多系統(tǒng)中,只要有報(bào)表出現(xiàn)就有需求要實(shí)現(xiàn)Excel數(shù)據(jù)導(dǎo)出功能。在一個(gè)系統(tǒng)中,客戶起初提出的需求是實(shí)現(xiàn)“全部導(dǎo)出”、“按選擇導(dǎo)出”、“導(dǎo)出本頁”。為此,我們設(shè)計(jì)了一個(gè)單選框,并在后臺(tái)程序中編寫了一個(gè)if語句,如果選擇的是“全部導(dǎo)出”,則查詢所有記錄并導(dǎo)出;如果選擇的是“按選擇導(dǎo)出”,則從前端獲得一個(gè)主鍵列表,即用戶已選擇的行,以此作為條件查詢導(dǎo)出;如果選擇的是“導(dǎo)出本頁”,則查詢本頁數(shù)據(jù)并導(dǎo)出。
這樣的設(shè)計(jì)沒有問題,也是大多數(shù)人首先想到的設(shè)計(jì)。但是,多個(gè)不同的選擇放在一個(gè)類中必將為功能的擴(kuò)展帶來麻煩。隨后,客戶提出了新的需求,按頁導(dǎo)出,即根據(jù)客戶的要求,從第幾頁到第幾頁進(jìn)行導(dǎo)出。按照前面的設(shè)計(jì),我們必然是在原有基礎(chǔ)上再增加一個(gè)if語句,實(shí)現(xiàn)按頁導(dǎo)出。
但這樣的設(shè)計(jì)違反了OCP原則,也是大多數(shù)系統(tǒng)代碼質(zhì)量下降的重要原因之一。在一些文章中,if語句被稱為“罪惡之源”,因?yàn)榇罅渴褂胕f語句將會(huì)大大降低系統(tǒng)的可讀性、可維護(hù)性與易變更性,使系統(tǒng)難于維護(hù)。因?yàn)椴粩嗵砑拥膇f語句很快會(huì)使代碼由數(shù)百行膨脹到幾千行,還會(huì)大量摻雜各種重復(fù)代碼與糟糕設(shè)計(jì)。其根本原因就在于,它讓一個(gè)類承載了過多的職責(zé),降低了功能內(nèi)聚而提高了功能耦合。它不僅加大了我們修改代碼的難度,也將加大我們測試代碼的成本,因?yàn)槿魏我豁?xiàng)修改都必須要對所有功能進(jìn)行測試。
因此,我們需要調(diào)整我們的代碼結(jié)構(gòu),改變我們的設(shè)計(jì)(到這里也許你開始理解我所說的改變代碼結(jié)構(gòu)以適應(yīng)新的需求的含義了吧)。我們說擴(kuò)展新功能的設(shè)計(jì)應(yīng)當(dāng)符合OCP原則。怎樣的設(shè)計(jì)才是符合OCP原則的呢?首先可以想到的是,讓“按頁導(dǎo)出”這個(gè)功能的代碼放到另一個(gè)類中,而不寫在原有類中。比如,我們可以創(chuàng)建一個(gè)新類ExportPageRange,通過接口Exporter接入到原類ExportBus,讓ExportBus調(diào)用其相應(yīng)的方法:
但是,這樣的設(shè)計(jì)我們依然需要修改原類ExportBus,在if語句中調(diào)用接口:
加粗部分是我們不得不在原類中添加的代碼。如果不使用這個(gè)if語句而讓Exporter接口的實(shí)現(xiàn)類與判斷條件建立一種聯(lián)系,則問題可以得到解決。要實(shí)現(xiàn)這種聯(lián)系有很多方法,其中一個(gè)方法就是建立配置文件,讓配置文件中的名稱與實(shí)現(xiàn)類關(guān)聯(lián)起來就可以了,為此我們需要這樣設(shè)計(jì):
然后進(jìn)行這樣的配置:
這樣,配置文件中的entrykey就與導(dǎo)出程序的實(shí)現(xiàn)類建立了聯(lián)系,因此在ExportBus中原來的那個(gè)if語句就演變成了這樣:
加粗的部分實(shí)質(zhì)性替代了原來那個(gè)if語句。這樣的設(shè)計(jì),讓各個(gè)不同類型的導(dǎo)出程序得到有效解耦,然后通過接口與配置文件實(shí)現(xiàn)動(dòng)態(tài)地裝配。這就是一種典型的可擴(kuò)展點(diǎn)設(shè)計(jì),當(dāng)我們還有新的導(dǎo)出類型的功能需要擴(kuò)展的時(shí)候,不需要修改原有的任何代碼,而只需添加一個(gè)Exporter接口新的實(shí)現(xiàn)類,再進(jìn)行相應(yīng)的配置,功能就可以實(shí)現(xiàn)。這樣的設(shè)計(jì)是可以滿足OCP原則的,而在系統(tǒng)中實(shí)現(xiàn)這種可擴(kuò)展性設(shè)計(jì)的功能點(diǎn),我們就稱之為“可擴(kuò)展點(diǎn)”。
以上的設(shè)計(jì)是我們最終應(yīng)當(dāng)實(shí)現(xiàn)的設(shè)計(jì),是結(jié)果。但要達(dá)到這樣的設(shè)計(jì),即分析整個(gè)設(shè)計(jì)的過程,我們真的沒有修改原程序嗎?不,我們修改了。那么這怎么叫符合OCP原則呢?問題十分犀利哈。轉(zhuǎn)了那么大一圈,現(xiàn)在才是我要真正提出我的觀點(diǎn)的時(shí)候了。我認(rèn)為,要改善遺留系統(tǒng)的可維護(hù)性,要遵守OCP原則,并不是意味著實(shí)現(xiàn)新需求時(shí)不能修改原有代碼。要遵從“兩頂帽子”的設(shè)計(jì)原則,先重構(gòu)原有的代碼,使其具有可擴(kuò)展功能,然后再添加新程序,使其滿足OCP原則,這才是可擴(kuò)展設(shè)計(jì)的關(guān)鍵之所在。
具體來說,就是第一步修改代碼,第二步添加功能。第一步,修改原有代碼,在保證原有功能不變的前提下,設(shè)計(jì)出可擴(kuò)展點(diǎn),使其在以后添加新功能時(shí)不必修改原有代碼。在本例中就是將原有的三種導(dǎo)出方式從原有代碼中抽取出來,形成Exporter接口與ExportAll、ExportOnePage、ExportChosen三個(gè)實(shí)現(xiàn)類,以及它們的配置文件。這樣,Exporter接口就是數(shù)據(jù)導(dǎo)出方式的可擴(kuò)展點(diǎn)。這時(shí),由于沒有添加任何新功能,我們可以編寫測試代碼進(jìn)行測試,或者手工測試。
第二步,就是添加新功能。由于可擴(kuò)展點(diǎn)已經(jīng)做出來了,剩下的工作其實(shí)就很簡單了:編寫實(shí)現(xiàn)類ExportPageRange,然后配置到系統(tǒng)中,整個(gè)設(shè)計(jì)符合OCP原則。功能擴(kuò)展就應(yīng)當(dāng)這樣做,才能使我們的軟件在維護(hù)中始終能保持高質(zhì)量的代碼。
(續(xù))
相關(guān)文檔
遺留系統(tǒng):IT攻城獅永遠(yuǎn)的痛
需求變更是罪惡之源嗎?
系統(tǒng)重構(gòu)是個(gè)什么玩意兒
我們應(yīng)當(dāng)改變我們的設(shè)計(jì)習(xí)慣
小步快跑是這樣玩的(上)
小步快跑是這樣玩的(下)
代碼復(fù)用應(yīng)該這樣做(1)
代碼復(fù)用應(yīng)該這樣做(2)
代碼復(fù)用應(yīng)該這樣做(3)
做好代碼復(fù)用不簡單
軟件可以這樣功能擴(kuò)展
過程擴(kuò)展與放置鉤子
特別說明:希望網(wǎng)友們在轉(zhuǎn)載本文時(shí),應(yīng)當(dāng)注明作者或出處,以示對作者的尊重,謝謝!
然而,事情總是這樣的,每個(gè)系統(tǒng)當(dāng)我們進(jìn)行初次的設(shè)計(jì)時(shí),設(shè)計(jì)思路、程序結(jié)構(gòu)總是比較完美的??墒钱?dāng)初次設(shè)計(jì)結(jié)束后,我們在日后的維護(hù)中,開始往系統(tǒng)里添加新功能時(shí),系統(tǒng)開始不完美了,甚至開始出現(xiàn)問題了,新增的功能總是或多或少有些水土不服。怎么辦呢?要保證每次需求的變更時(shí)軟件質(zhì)量不會(huì)下降,必須記住這樣一個(gè)原則:先重構(gòu)再添加新功能。
添加新功能前先重構(gòu)原有系統(tǒng),其目的有兩個(gè):
1. 軟件的設(shè)計(jì)總是與軟件的復(fù)雜程度有關(guān)的,原有的設(shè)計(jì)是在原有需求不復(fù)雜的條件下做出的,但隨著新功能的加入,軟件復(fù)雜度在發(fā)生著變化,因此必須要調(diào)整原有的設(shè)計(jì)以適應(yīng)新的需求;
2. 為了提高軟件的可維護(hù)性與易變更性,添加新功能應(yīng)遵循OCP原則。而要遵循OCP原則,我們應(yīng)當(dāng)在不添加新功能的前提下先進(jìn)行重構(gòu),設(shè)計(jì)出可擴(kuò)展點(diǎn)出來,然后再添加新功能。
是的,明白這兩點(diǎn)非常重要。軟件維護(hù)越來越困難,不是因?yàn)榭蛻籼岢隽诵枨笞兏?,而是因?yàn)槲覀儧]有隨著軟件復(fù)雜度的增加改變我們的軟件結(jié)構(gòu)。軟件需求起初比較簡單,是幾乎所有軟件的共性。但隨著軟件復(fù)雜度的增加,我們卻不敢有效地調(diào)整現(xiàn)有的軟件結(jié)構(gòu),以適應(yīng)新的需求,這就真正是我們的問題了。不敢調(diào)整,是害怕原有功能會(huì)出錯(cuò),但不調(diào)整,則意味著我們軟件設(shè)計(jì)的問題會(huì)越來越大,進(jìn)而越來越難于維護(hù)。改與不改,我們面臨著兩難的抉擇。
解決這個(gè)兩難的難題其實(shí)不難,實(shí)際上就是一層窗戶紙一桶就破了。試想,我們不敢修改原有代碼的真正原因是因?yàn)楹ε赂某鰡栴}影響原有功能的正常運(yùn)行。那么,我們找一個(gè)方法使我們在修改原有代碼時(shí)不會(huì)出現(xiàn)問題,換句話說是出現(xiàn)問題以后會(huì)及時(shí)發(fā)現(xiàn),則問題就可以解決,這個(gè)方法就是重構(gòu)與測試。
客戶判斷一個(gè)功能是否正常運(yùn)行的標(biāo)準(zhǔn),就是當(dāng)輸入一個(gè)值后,能得到客戶期望的結(jié)果,不管系統(tǒng)內(nèi)部是怎樣運(yùn)行的。因此,建立這樣一個(gè)測試用例,讓軟件系統(tǒng)在重構(gòu)前后都能通過這些測試用例,就可以保證重構(gòu)的正確性(關(guān)于如何建立,我們還會(huì)在后面仔細(xì)討論)。重構(gòu)以后,外部功能是一致的,但內(nèi)部程序結(jié)構(gòu)卻變得更加易于添加新的功能,使新的功能與原有系統(tǒng)可以有機(jī)地融為一體,這才是我們的目的。說起來比較抽象,我們來舉一個(gè)示例吧:
在許多系統(tǒng)中,只要有報(bào)表出現(xiàn)就有需求要實(shí)現(xiàn)Excel數(shù)據(jù)導(dǎo)出功能。在一個(gè)系統(tǒng)中,客戶起初提出的需求是實(shí)現(xiàn)“全部導(dǎo)出”、“按選擇導(dǎo)出”、“導(dǎo)出本頁”。為此,我們設(shè)計(jì)了一個(gè)單選框,并在后臺(tái)程序中編寫了一個(gè)if語句,如果選擇的是“全部導(dǎo)出”,則查詢所有記錄并導(dǎo)出;如果選擇的是“按選擇導(dǎo)出”,則從前端獲得一個(gè)主鍵列表,即用戶已選擇的行,以此作為條件查詢導(dǎo)出;如果選擇的是“導(dǎo)出本頁”,則查詢本頁數(shù)據(jù)并導(dǎo)出。
String exportTypeName = (String)params.get("exportType"); if("exportAll".equals(exportTypeName)) { //全部導(dǎo)出的代碼 } else if("exportChoosen".equals(exportTypeName)) { //按選擇導(dǎo)出的代碼 } else if("exportOnePage".equals(exportTypeName)) { //導(dǎo)出本頁的代碼 }
這樣的設(shè)計(jì)沒有問題,也是大多數(shù)人首先想到的設(shè)計(jì)。但是,多個(gè)不同的選擇放在一個(gè)類中必將為功能的擴(kuò)展帶來麻煩。隨后,客戶提出了新的需求,按頁導(dǎo)出,即根據(jù)客戶的要求,從第幾頁到第幾頁進(jìn)行導(dǎo)出。按照前面的設(shè)計(jì),我們必然是在原有基礎(chǔ)上再增加一個(gè)if語句,實(shí)現(xiàn)按頁導(dǎo)出。
String exportTypeName = (String)params.get("exportType"); if("exportAll".equals(exportTypeName)) { //全部導(dǎo)出的代碼 } else if("exportChoosen".equals(exportTypeName)) { //按選擇導(dǎo)出的代碼 } else if("exportOnePage".equals(exportTypeName)) { //導(dǎo)出本頁的代碼 } else if("exportPageRange".equals(exportTypeName)) { //按頁導(dǎo)出的代碼 }
但這樣的設(shè)計(jì)違反了OCP原則,也是大多數(shù)系統(tǒng)代碼質(zhì)量下降的重要原因之一。在一些文章中,if語句被稱為“罪惡之源”,因?yàn)榇罅渴褂胕f語句將會(huì)大大降低系統(tǒng)的可讀性、可維護(hù)性與易變更性,使系統(tǒng)難于維護(hù)。因?yàn)椴粩嗵砑拥膇f語句很快會(huì)使代碼由數(shù)百行膨脹到幾千行,還會(huì)大量摻雜各種重復(fù)代碼與糟糕設(shè)計(jì)。其根本原因就在于,它讓一個(gè)類承載了過多的職責(zé),降低了功能內(nèi)聚而提高了功能耦合。它不僅加大了我們修改代碼的難度,也將加大我們測試代碼的成本,因?yàn)槿魏我豁?xiàng)修改都必須要對所有功能進(jìn)行測試。
因此,我們需要調(diào)整我們的代碼結(jié)構(gòu),改變我們的設(shè)計(jì)(到這里也許你開始理解我所說的改變代碼結(jié)構(gòu)以適應(yīng)新的需求的含義了吧)。我們說擴(kuò)展新功能的設(shè)計(jì)應(yīng)當(dāng)符合OCP原則。怎樣的設(shè)計(jì)才是符合OCP原則的呢?首先可以想到的是,讓“按頁導(dǎo)出”這個(gè)功能的代碼放到另一個(gè)類中,而不寫在原有類中。比如,我們可以創(chuàng)建一個(gè)新類ExportPageRange,通過接口Exporter接入到原類ExportBus,讓ExportBus調(diào)用其相應(yīng)的方法:
但是,這樣的設(shè)計(jì)我們依然需要修改原類ExportBus,在if語句中調(diào)用接口:
String exportTypeName = (String)params.get("exportType"); If ("exportAll".equals(exportTypeName)) { //全部導(dǎo)出的代碼 } else if ("exportChoosen".equals(exportTypeName)) { //按選擇導(dǎo)出的代碼 } else if ("exportOnePage".equals(exportTypeName)) { //導(dǎo)出本頁的代碼 } else if ("exportPageRange".equals(exportTypeName)) { //按頁導(dǎo)出的代碼 Exporter exporter = new ExportPageRange(); exporter.doExport(resultset); return exporter.getFileInfo(); }
加粗部分是我們不得不在原類中添加的代碼。如果不使用這個(gè)if語句而讓Exporter接口的實(shí)現(xiàn)類與判斷條件建立一種聯(lián)系,則問題可以得到解決。要實(shí)現(xiàn)這種聯(lián)系有很多方法,其中一個(gè)方法就是建立配置文件,讓配置文件中的名稱與實(shí)現(xiàn)類關(guān)聯(lián)起來就可以了,為此我們需要這樣設(shè)計(jì):
然后進(jìn)行這樣的配置:
<bean id="exportBus" class="com...reporter.bus.impl.ExportBusImpl"> <description>導(dǎo)出數(shù)據(jù)BUS</description> <property name="exportTypes"> <map> <entry key="exportAll"><!-- 全部導(dǎo)出 --> <bean class="com...reporter.export.ExportAll"/> </entry> <entry key="exportOnePage"><!-- 導(dǎo)出本頁 --> <bean class="com...reporter.export.ExportOnePage"/> </entry> <entry key="exportChosen"><!-- 按選擇導(dǎo)出 --> <bean class="com...reporter.export.ExportChosen"/> </entry> <entry key="exportPageRange"><!-- 按頁導(dǎo)出 --> <bean class="com...reporter.export.ExportPageRange"/> </entry> </map> </property> </bean>
這樣,配置文件中的entrykey就與導(dǎo)出程序的實(shí)現(xiàn)類建立了聯(lián)系,因此在ExportBus中原來的那個(gè)if語句就演變成了這樣:
String exportTypeName = (String)params.get("exportType"); Exporter exporter = exportTypes.get(exportTypeName); exporter.doExport(resultset); return exporter.getFileInfo();
加粗的部分實(shí)質(zhì)性替代了原來那個(gè)if語句。這樣的設(shè)計(jì),讓各個(gè)不同類型的導(dǎo)出程序得到有效解耦,然后通過接口與配置文件實(shí)現(xiàn)動(dòng)態(tài)地裝配。這就是一種典型的可擴(kuò)展點(diǎn)設(shè)計(jì),當(dāng)我們還有新的導(dǎo)出類型的功能需要擴(kuò)展的時(shí)候,不需要修改原有的任何代碼,而只需添加一個(gè)Exporter接口新的實(shí)現(xiàn)類,再進(jìn)行相應(yīng)的配置,功能就可以實(shí)現(xiàn)。這樣的設(shè)計(jì)是可以滿足OCP原則的,而在系統(tǒng)中實(shí)現(xiàn)這種可擴(kuò)展性設(shè)計(jì)的功能點(diǎn),我們就稱之為“可擴(kuò)展點(diǎn)”。
以上的設(shè)計(jì)是我們最終應(yīng)當(dāng)實(shí)現(xiàn)的設(shè)計(jì),是結(jié)果。但要達(dá)到這樣的設(shè)計(jì),即分析整個(gè)設(shè)計(jì)的過程,我們真的沒有修改原程序嗎?不,我們修改了。那么這怎么叫符合OCP原則呢?問題十分犀利哈。轉(zhuǎn)了那么大一圈,現(xiàn)在才是我要真正提出我的觀點(diǎn)的時(shí)候了。我認(rèn)為,要改善遺留系統(tǒng)的可維護(hù)性,要遵守OCP原則,并不是意味著實(shí)現(xiàn)新需求時(shí)不能修改原有代碼。要遵從“兩頂帽子”的設(shè)計(jì)原則,先重構(gòu)原有的代碼,使其具有可擴(kuò)展功能,然后再添加新程序,使其滿足OCP原則,這才是可擴(kuò)展設(shè)計(jì)的關(guān)鍵之所在。
具體來說,就是第一步修改代碼,第二步添加功能。第一步,修改原有代碼,在保證原有功能不變的前提下,設(shè)計(jì)出可擴(kuò)展點(diǎn),使其在以后添加新功能時(shí)不必修改原有代碼。在本例中就是將原有的三種導(dǎo)出方式從原有代碼中抽取出來,形成Exporter接口與ExportAll、ExportOnePage、ExportChosen三個(gè)實(shí)現(xiàn)類,以及它們的配置文件。這樣,Exporter接口就是數(shù)據(jù)導(dǎo)出方式的可擴(kuò)展點(diǎn)。這時(shí),由于沒有添加任何新功能,我們可以編寫測試代碼進(jìn)行測試,或者手工測試。
第二步,就是添加新功能。由于可擴(kuò)展點(diǎn)已經(jīng)做出來了,剩下的工作其實(shí)就很簡單了:編寫實(shí)現(xiàn)類ExportPageRange,然后配置到系統(tǒng)中,整個(gè)設(shè)計(jì)符合OCP原則。功能擴(kuò)展就應(yīng)當(dāng)這樣做,才能使我們的軟件在維護(hù)中始終能保持高質(zhì)量的代碼。
(續(xù))
相關(guān)文檔
遺留系統(tǒng):IT攻城獅永遠(yuǎn)的痛
需求變更是罪惡之源嗎?
系統(tǒng)重構(gòu)是個(gè)什么玩意兒
我們應(yīng)當(dāng)改變我們的設(shè)計(jì)習(xí)慣
小步快跑是這樣玩的(上)
小步快跑是這樣玩的(下)
代碼復(fù)用應(yīng)該這樣做(1)
代碼復(fù)用應(yīng)該這樣做(2)
代碼復(fù)用應(yīng)該這樣做(3)
做好代碼復(fù)用不簡單
軟件可以這樣功能擴(kuò)展
過程擴(kuò)展與放置鉤子
特別說明:希望網(wǎng)友們在轉(zhuǎn)載本文時(shí),應(yīng)當(dāng)注明作者或出處,以示對作者的尊重,謝謝!
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
