隨著我們對(duì)Java編程開發(fā)語言的掌握,對(duì)于不同場景下使用哪種設(shè)計(jì)模式會(huì)有更清晰的判斷。
創(chuàng)新互聯(lián)建站是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷策劃、小程序定制開發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動(dòng)互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立10多年以來,已經(jīng)為上千多家發(fā)電機(jī)回收各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)?,F(xiàn)在,服務(wù)的上千多家客戶與我們一路同行,見證我們的成長;未來,我們一起分享成功的喜悅。
下面IT培訓(xùn)就一起來了解一下,JavaScript編程中的幾種常見設(shè)計(jì)模式都有哪些類型。
設(shè)計(jì)原則單一職責(zé)原則(SRP)一個(gè)對(duì)象或方法只做一件事情。
如果一個(gè)方法承擔(dān)了過多的職責(zé),那么在需求的變遷過程中,需要改寫這個(gè)方法的可能性就越大。
應(yīng)該把對(duì)象或方法劃分成較小的粒度少知識(shí)原則(LKP)一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少地與其他實(shí)體發(fā)生相互作用應(yīng)當(dāng)盡量減少對(duì)象之間的交互。
如果兩個(gè)對(duì)象之間不必彼此直接通信,那么這兩個(gè)對(duì)象就不要發(fā)生直接的相互聯(lián)系,可以轉(zhuǎn)交給三方進(jìn)行處理開放-封閉原則(OCP)軟件實(shí)體(類、模塊、函數(shù))等應(yīng)該是可以擴(kuò)展的,但是不可修改當(dāng)需要改變一個(gè)程序的功能或者給這個(gè)程序增加新功能的時(shí)候,可以使用增加代碼的方式,盡量避免改動(dòng)程序的源代碼,防止影響原系統(tǒng)的穩(wěn)定什么是設(shè)計(jì)模式作者的這個(gè)說明解釋得挺好假設(shè)有一個(gè)空房間,我們要日復(fù)一日地往里面放一些東西。
簡單的辦法當(dāng)然是把這些東西直接扔進(jìn)去,但是時(shí)間久了,就會(huì)發(fā)現(xiàn)很難從這個(gè)房子里找到自己想要的東西,要調(diào)整某幾樣?xùn)|西的位置也不容易。
所以在房間里做一些柜子也許是個(gè)更好的選擇,雖然柜子會(huì)增加我們的成本,但它可以在維護(hù)階段為我們帶來好處。
使用這些柜子存放東西的規(guī)則,或許就是一種模式
原則包括:
單一職責(zé)原則:一個(gè)類只做它該做的事情。(單一職責(zé)原則想表達(dá)的就是”高內(nèi)聚”,寫代碼最終極的原則只有六個(gè)字”高內(nèi)聚、低耦合”,就如同葵花寶典或辟邪劍譜的中心思想就八個(gè)字”欲練此功必先自宮”,所謂的高內(nèi)聚就是一個(gè)代碼模塊只完成一項(xiàng)功能,在面向?qū)ο笾?,如果只讓一個(gè)類完成它該做的事,而不涉及與它無關(guān)的領(lǐng)域就是踐行了高內(nèi)聚的原則,這個(gè)類就只有單一職責(zé)。提醒大家有一句話叫”因?yàn)閷W?,所以專業(yè)”,一個(gè)對(duì)象如果承擔(dān)太多的職責(zé),那么注定它什么都做不好。這個(gè)世界上任何好的東西都有兩個(gè)特征,一個(gè)是功能單一,好的相機(jī)絕對(duì)不是電視購物里面賣的那種一個(gè)機(jī)器有一百多種功能的,它基本上只能照相;另一個(gè)是模塊化,好的自行車是組裝車,從減震叉、剎車到變速器,所有的部件都是可以拆卸和重新組裝的,好的乒乓球拍也不是成品拍,一定是底板和膠皮可以拆分和自行組裝的,一個(gè)好的軟件系統(tǒng),它里面的每個(gè)功能模塊也應(yīng)該是可以輕易的拿到其他系統(tǒng)中使用的,這樣才能實(shí)現(xiàn)軟件復(fù)用的目標(biāo)。)
開閉原則:軟件實(shí)體應(yīng)當(dāng)對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。(在理想的狀態(tài)下,當(dāng)我們需要為一個(gè)軟件系統(tǒng)增加新功能時(shí),只需要從原來的系統(tǒng)派生出一些新類就可以,不需要修改原來的任何一行代碼。要做到開閉有兩個(gè)要點(diǎn):①抽象是關(guān)鍵,一個(gè)系統(tǒng)中如果沒有抽象類或接口系統(tǒng)就沒有擴(kuò)展點(diǎn);②封裝可變性,將系統(tǒng)中的各種可變因素封裝到一個(gè)繼承結(jié)構(gòu)中,如果多個(gè)可變因素混雜在一起,系統(tǒng)將變得復(fù)雜而混亂,如果不清楚如何封裝可變性,可以參考《設(shè)計(jì)模式精解》一書中對(duì)橋梁模式的講解的章節(jié)。)
依賴倒轉(zhuǎn)原則:面向接口編程。(該原則說得直白和具體一些就是聲明方法的參數(shù)類型、方法的返回類型、變量的引用類型時(shí),盡可能使用抽象類型而不用具體類型,因?yàn)槌橄箢愋涂梢员凰娜魏我粋€(gè)子類型所替代,請(qǐng)參考下面的里氏替換原則。)
里氏替換原則:任何時(shí)候都可以用子類型替換掉父類型。(關(guān)于里氏替換原則的描述,Barbara Liskov女士的描述比這個(gè)要復(fù)雜得多,但簡單的說就是能用父類型的地方就一定能使用子類型。里氏替換原則可以檢查繼承關(guān)系是否合理,如果一個(gè)繼承關(guān)系違背了里氏替換原則,那么這個(gè)繼承關(guān)系一定是錯(cuò)誤的,需要對(duì)代碼進(jìn)行重構(gòu)。例如讓貓繼承狗,或者狗繼承貓,又或者讓正方形繼承長方形都是錯(cuò)誤的繼承關(guān)系,因?yàn)槟愫苋菀渍业竭`反里氏替換原則的場景。需要注意的是:子類一定是增加父類的能力而不是減少父類的能力,因?yàn)樽宇惐雀割惖哪芰Ω?,把能力多的?duì)象當(dāng)成能力少的對(duì)象來用當(dāng)然沒有任何問題。
接口隔離原則:接口要小而專,絕不能大而全。(臃腫的接口是對(duì)接口的污染,既然接口表示能力,那么一個(gè)接口只應(yīng)該描述一種能力,接口也應(yīng)該是高度內(nèi)聚的。例如,琴棋書畫就應(yīng)該分別設(shè)計(jì)為四個(gè)接口,而不應(yīng)設(shè)計(jì)成一個(gè)接口中的四個(gè)方法,因?yàn)槿绻O(shè)計(jì)成一個(gè)接口中的四個(gè)方法,那么這個(gè)接口很難用,畢竟琴棋書畫四樣都精通的人還是少數(shù),而如果設(shè)計(jì)成四個(gè)接口,會(huì)幾項(xiàng)就實(shí)現(xiàn)幾個(gè)接口,這樣的話每個(gè)接口被復(fù)用的可能性是很高的。Java中的接口代表能力、代表約定、代表角色,能否正確的使用接口一定是編程水平高低的重要標(biāo)識(shí)。)
合成聚合復(fù)用原則:
優(yōu)先使用聚合或合成關(guān)系復(fù)用代碼。(通過繼承來復(fù)用代碼是面向?qū)ο蟪绦蛟O(shè)計(jì)中被濫用得最多的東西,因?yàn)樗械慕炭茣紵o一例外的對(duì)繼承進(jìn)行了鼓吹從而誤導(dǎo)了初學(xué)者,類與類之間簡單的說有三種關(guān)系,Is-A關(guān)系、Has-A關(guān)系、Use-A關(guān)系,分別代表繼承、關(guān)聯(lián)和依賴。其中,關(guān)聯(lián)關(guān)系根據(jù)其關(guān)聯(lián)的強(qiáng)度又可以進(jìn)一步劃分為關(guān)聯(lián)、聚合和合成,但說白了都是Has-A關(guān)系,合成聚合復(fù)用原則想表達(dá)的是優(yōu)先考慮Has-A關(guān)系而不是Is-A關(guān)系復(fù)用代碼,原因嘛可以自己從百度上找到一萬個(gè)理由,浙江優(yōu)就業(yè)需要說明的是,即使在Java的API中也有不少濫用繼承的例子,例如Properties類繼承了Hashtable類,Stack類繼承了Vector類,這些繼承明顯就是錯(cuò)誤的,更好的做法是在Properties類中放置一個(gè)Hashtable類型的成員并且將其鍵和值都設(shè)置為字符串來存儲(chǔ)數(shù)據(jù),而Stack類的設(shè)計(jì)也應(yīng)該是在Stack類中放一個(gè)Vector對(duì)象來存儲(chǔ)數(shù)據(jù)。記住:任何時(shí)候都不要繼承工具類,工具是可以擁有并可以使用的,而不是拿來繼承的。)
法則指迪米特法則:迪米特法則又叫最少知識(shí)原則,一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其他對(duì)象有盡可能少的了解。(迪米特法則簡單的說就是如何做到”低耦合”,門面模式和調(diào)停者模式就是對(duì)迪米特法則的踐行。對(duì)于門面模式可以舉一個(gè)簡單的例子,你去一家公司洽談業(yè)務(wù),你不需要了解這個(gè)公司內(nèi)部是如何運(yùn)作的,你甚至可以對(duì)這個(gè)公司一無所知,去的時(shí)候只需要找到公司入口處的前臺(tái)美女,告訴她們你要做什么,她們會(huì)找到合適的人跟你接洽,前臺(tái)的美女就是公司這個(gè)系統(tǒng)的門面。再復(fù)雜的系統(tǒng)都可以為用戶提供一個(gè)簡單的門面,Java Web開發(fā)中作為前端控制器的Servlet或Filter不就是一個(gè)門面嗎,瀏覽器對(duì)服務(wù)器的運(yùn)作方式一無所知,但是通過前端控制器就能夠根據(jù)你的請(qǐng)求得到相應(yīng)的服務(wù)。調(diào)停者模式也可以舉一個(gè)簡單的例子來說明,例如一臺(tái)計(jì)算機(jī),CPU、內(nèi)存、硬盤、顯卡、聲卡各種設(shè)備需要相互配合才能很好的工作,但是如果這些東西都直接連接到一起,計(jì)算機(jī)的布線將異常復(fù)雜,在這種情況下,主板作為一個(gè)調(diào)停者的身份出現(xiàn),它將各個(gè)設(shè)備連接在一起而不需要每個(gè)設(shè)備之間直接交換數(shù)據(jù),這樣就減小了系統(tǒng)的耦合度和復(fù)雜度)
這個(gè)問題在Java中屬于比較基礎(chǔ)的問題,但是也請(qǐng)題主不要灰心。面試是一個(gè)考量綜合素質(zhì)的過程,即使一兩道題發(fā)揮不好也仍然擁有機(jī)會(huì)。
一些小職責(zé)可以用內(nèi)部類,static class A{} ,源文件不須太多
設(shè)計(jì)也是對(duì)已經(jīng)存在的問題進(jìn)行分類,而不在抽象上做不實(shí)際的細(xì)分吧..
至于類多,可以參考一派的觀點(diǎn)OOP是有殘疾的,純OO經(jīng)常導(dǎo)致畫蛇添足...代碼量翻倍
退回到過程和對(duì)象混用...盡量少分類,多用函數(shù)式純函數(shù),
現(xiàn)在的python就持這類理念
軟件開發(fā)原則問題我們已經(jīng)給大家在前幾期的文章中多次強(qiáng)調(diào)了其重要性。
尤其是不能違反用戶的常規(guī)使用習(xí)慣。
今天,IT培訓(xùn)就一起來了解一下,軟件開發(fā)原則中的六個(gè)比較重要的原則都有哪些。
一、單一職責(zé)原則1、單一職責(zé)定義單一職責(zé)原則:一個(gè)類只負(fù)責(zé)一個(gè)功能領(lǐng)域中的相應(yīng)職責(zé),或者可以定義為:就一個(gè)類而言,應(yīng)該只有一個(gè)引起它變化的原因。
單一職責(zé)原則告訴我們:一個(gè)類不能太“累”!在軟件系統(tǒng)中,一個(gè)類承擔(dān)的職責(zé)越多,它被復(fù)用的可能性就越小,而且一個(gè)類承擔(dān)的職責(zé)過多,就相當(dāng)于將這些職責(zé)耦合在一起,當(dāng)其中一個(gè)職責(zé)變化時(shí),可能會(huì)影響其他職責(zé)的運(yùn)作,因此要將這些職責(zé)進(jìn)行分離,將不同的職責(zé)封裝在不同的類中,即將不同的變化原因封裝在不同的類中,如果多個(gè)職責(zé)總是同時(shí)發(fā)生改變則可將它們封裝在同一類中。
2、單一職責(zé)優(yōu)點(diǎn)1)降低了類的復(fù)雜度。
一個(gè)類只負(fù)責(zé)一項(xiàng)職責(zé)比負(fù)責(zé)多項(xiàng)職責(zé)要簡單得多。
2)提高了代碼的可讀性。
一個(gè)類簡單了,可讀性自然就提高了。
3)提高了系統(tǒng)的可維護(hù)性。
代碼的可讀性高了,并且修改一項(xiàng)職責(zé)對(duì)其他職責(zé)影響降低了,可維護(hù)性自然就提高了。
4)變更引起的風(fēng)險(xiǎn)變低了。
單一職責(zé)大的優(yōu)點(diǎn)就是修改一個(gè)功能,對(duì)其他功能的影響顯著降低。
二、里氏代換原則這個(gè)和單一職責(zé)原則比起來,顯然就好理解多了,而且也不那么模糊不清。
1、定義官方定義:所有引用基類(父類)的地方必須能透明地使用其子類的對(duì)象。
簡單理解就是:子類一般不該重寫父類的方法,因?yàn)楦割惖姆椒ㄒ话愣际菍?duì)外公布的接口,是具有不可變性的,你不該將一些不該變化的東西給修改掉。
是不是感覺這個(gè)原則不太招人喜歡,因?yàn)槲覀冊(cè)趯懘a的時(shí)候經(jīng)常會(huì)去重寫父類的方法來滿足我們的需求。
而且在模板方法模式,缺省適配器,裝飾器模式等一些設(shè)計(jì)模式都會(huì)采用重寫父類的方法。
怎么說呢,里氏代換原則的主要目的主要是防止繼承所帶來的弊端。
繼承的弊端:繼承作為面向?qū)ο笕筇匦灾唬诮o程序設(shè)計(jì)帶來巨大便利的同時(shí),也帶來了弊端。
繼承會(huì)增加了對(duì)象間的耦合性,如果一個(gè)類被其他的類所繼承,則當(dāng)這個(gè)類需要修改時(shí),必須考慮到所有的子類,并且父類修改后,所有涉及到子類的功能都有可能會(huì)產(chǎn)生故障。
三、接口隔離原則1、定義當(dāng)一個(gè)接口太大時(shí),我們需要將它分割成一些更細(xì)小的接口,使用該接口的客戶端僅需知道與之相關(guān)的方法即可。
為什么要這么做呢?其實(shí)很好理解,因?yàn)槟銓?shí)現(xiàn)一個(gè)接口就是實(shí)現(xiàn)它所有的方法,但其實(shí)你并不需要它的所有方法,那就會(huì)產(chǎn)生:一個(gè)類實(shí)現(xiàn)了一個(gè)接口,里面很多方法都是空著的,只有個(gè)別幾個(gè)方法實(shí)現(xiàn)了。
這樣做不僅會(huì)強(qiáng)制實(shí)現(xiàn)的人不得不實(shí)現(xiàn)本來不該實(shí)現(xiàn)的方法,嚴(yán)重的是會(huì)給使用者造成假象,即這個(gè)實(shí)現(xiàn)類擁有接口中所有的行為,結(jié)果調(diào)用方法時(shí)卻沒收獲到想要的結(jié)果。