日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

JavaScript面向?qū)ο笾叽蠡驹瓌t實例詳解

瀏覽:215日期:2023-10-30 17:35:33

本文實例講述了JavaScript面向?qū)ο笾叽蠡驹瓌t。分享給大家供大家參考,具體如下:

面向?qū)ο缶幊逃凶约旱奶匦耘c原則,如果對于面向?qū)ο笥幸恍┝私獾脑?,面向?qū)ο笕筇卣?,封裝、繼承、多態(tài),如果對面向?qū)@三個概念不太了解,請參考面向?qū)ο笾齻€基本特征(javaScript)

單一職責(zé)

如果我們在編寫程序的時候,一類或者一個方法里面包含了太多方法,對于代碼的可讀性來說,無非是一場災(zāi)難,對于我們來說。所以為了解決這個問題,出現(xiàn)了單一職責(zé)。

什么是單一職責(zé)

單一職責(zé):又稱單一功能原則,面向?qū)ο笪鍌€基本原則(SOLID)之一。它規(guī)定一個類應(yīng)該只有一個發(fā)生變化的原因。(節(jié)選自百度百科)

按照上面說的,就是對一個類而言,應(yīng)該僅有一個引起它變化的原因。換句話說,一個類的功能要單一,只做與它相關(guān)的事情。在類的設(shè)計過程中要按職責(zé)進(jìn)行設(shè)計,彼此保持正交,互不干涉。

單一職責(zé)的好處 類的復(fù)雜性降低,實現(xiàn)什么職責(zé)都有清晰明確的定義 可讀性提高,復(fù)雜性降低,那當(dāng)然可讀性提高了 可維護(hù)性提高,可讀性提高,那當(dāng)然更容易維護(hù)了 變更引起的風(fēng)險降低,變更是必不可少的,如果接口的單一職責(zé)做得好,一個接口修改只對相應(yīng)的實現(xiàn)類有影響,對其他的接口無影響,這對系統(tǒng)的擴(kuò)展性、維護(hù)性都有非常大的幫助。實例

class ShoppinCar { constructor(){ this.goods = []; } addGoods(good){ this.goods = [good]; } getGoodsList(){ return this.goods; }}class Settlement { constructor(){ this.result = 0; } calculatePrice(list,key){ let allPrice = 0; list.forEach((el) => { allPrice += el[key]; }) this.result = allPrice; } getAllPrice(){ return this.result; }}

用上面的代碼來說ShoppinCar類存在兩個方法addGoods和getGoodsList,分別是添加商品和獲取商品列表。Settlement類中存在兩個方法calculatePrice和getAllPrice分別做的事情是計算價錢與獲取總價錢。ShoppinCar與Settlement都是在做自己的事情。添加商品與計算價格,雖然在業(yè)務(wù)上是相互依賴的,但是在代碼中分別用兩個類,然他們自己做自己的事情。其中任何一個類更改不會對另一個類進(jìn)行更改。

開閉原則

在一個類中暴露出去的方法,若這個方法變更了,則會產(chǎn)生很大的后果,可能導(dǎo)致其他依賴于這個方法且有不需要變更的業(yè)務(wù)造成大面積癱瘓。為了解決這個問題,可以單獨再寫一個方法,若這個方法與這個類中的其他方法相互依賴。

解決辦法:

把其中依賴的代碼copy一份到新的類中。 在新類中引用舊類中的方法。

兩種方法都不是最好的解決方案。

第一種方法會導(dǎo)致代碼大量的重復(fù),第二種方法會導(dǎo)致類與類之間互相依賴。

什么是開閉原則

開閉原則:“軟件中的對象(類,模塊,函數(shù)等等)應(yīng)該對于擴(kuò)展是開放的,但是對于修改是封閉的”,這意味著一個實體是允許在不改變它的源代碼的前提下變更它的行為。(節(jié)選自百度百科)

開閉原則對擴(kuò)展開放,對修改關(guān)閉,并不意味著不做任何修改,底層模塊的變更,必然要有高層模塊進(jìn)行耦合,否則就是一個孤立無意義的代碼片段。開閉原則是一個最基本的原則,另外六個原則都是開閉原則的具體形態(tài),是指導(dǎo)設(shè)計的工具和方法,而開閉原則才是精神領(lǐng)袖.

開閉原則好處 開閉原則有利于進(jìn)行單元測試 開閉原則可以提高復(fù)用性 開閉原則可以提高可維護(hù)性 面向?qū)ο箝_發(fā)的要求實例

class Drag { down(){ // ... } move(){ // ... // 對拖拽沒有做任何限制可以隨意拖拽 } up(){ // ... } }class LimitDrag extends Drag { move(){ // ... // 重寫該方法對拖拽進(jìn)行限制處理 }}

在LimitDrag中重寫了move方法,若修改了可以滿足兩種需求,一種是限制型拖拽,一種是不限制型拖拽,任何一個更改了另外一個還是可以正常運行。

里氏替換

每個開發(fā)人員在使用別人的組件時,只需知道組件的對外裸露的接口,那就是它全部行為的集合,至于內(nèi)部到底是怎么實現(xiàn)的,無法知道,也無須知道。所以,對于使用者而言,它只能通過接口實現(xiàn)自己的預(yù)期,如果組件接口提供的行為與使用者的預(yù)期不符,錯誤便產(chǎn)生了。里氏替換原則就是在設(shè)計時避免出現(xiàn)派生類與基類不一致的行為。

什么是里氏替換

里氏替換原則:OCP作為OO的高層原則,主張使用“抽象(Abstraction)”和“多態(tài)(Polymorphism)”將設(shè)計中的靜態(tài)結(jié)構(gòu)改為動態(tài)結(jié)構(gòu),維持設(shè)計的封閉性?!俺橄蟆笔钦Z言提供的功能?!岸鄳B(tài)”由繼承語義實現(xiàn)。(節(jié)選自百度百科)

里氏替換好處 代碼共享,減少創(chuàng)建類的工作量,每個子類都擁有父類的方法和屬性 提高代碼的重用性 子類可以形似父類,但是又異于父類。 提高代碼的可擴(kuò)展性,實現(xiàn)父類的方法就可以了。許多開源框架的擴(kuò)展接口都是通過繼承父類來完成。 提高產(chǎn)品或項目的開放性實例

// 抽象槍類class AbstractGun { shoot(){ throw 'Abstract methods cannot be called'; }}// 步槍class Rifle extends AbstractGun { shoot(){ console.log('步槍射擊...'); }}// 狙擊槍class AUG extends Rifle { zoomOut(){ console.log('通過放大鏡觀察'); } shoot(){ console.log('AUG射擊...'); }}// 士兵class Soldier { constructor(){ this.gun = null; } setGun(gun){ this.gun = gun; } killEnemy(){ if(!this.gun){ throw '需要給我一把槍'; return; } console.log('士兵開始射擊...'); this.gun.shoot(); }}// 狙擊手class Snipper extends Soldier { killEnemy(aug){ if(!this.gun){ throw '需要給我一把槍'; return; } this.gun.zoomOut(); this.gun.shoot(); }}let soldier = new Soldier();soldier.setGun(new Rifle());soldier.killEnemy();let snipper = new Snipper();// 分配狙擊槍snipper.setGun(new AUG());snipper.killEnemy();snipper.setGun(new Rifle());// snipper.killEnemy(); // this.gun.zoomOut is not a function

從上述代碼中可以看出,子類和父類之間關(guān)系,子類方法一定是等于或大于父類的方法。子類能夠出現(xiàn)的父類不一定能出現(xiàn),但是父類出現(xiàn)的地方子類一定能夠出現(xiàn)。

依賴倒置

如果方法與方法之間或類與類之間,存在太多的依賴關(guān)系會導(dǎo)致代碼可讀性以及可維護(hù)性很差。依賴倒置原則能夠很好的解決這些問題。

什么是依賴倒置

依賴倒置原則:程序要依賴于抽象接口,不要依賴于具體實現(xiàn)。簡單的說就是要求對抽象進(jìn)行編程,不要對實現(xiàn)進(jìn)行編程,這樣就降低了客戶與實現(xiàn)模塊間的耦合。(節(jié)選自百度百科)

高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象 抽象不應(yīng)該依賴細(xì)節(jié) 細(xì)節(jié)應(yīng)該依賴抽象依賴倒置好處 通過依賴于接口,隔離了具體實現(xiàn)類 低一層的變動并不會導(dǎo)致高一層的變動 提高了代碼的容錯性、擴(kuò)展性和易于維護(hù)實例

// 抽象槍類class AbstractGun { shoot(){ throw 'Abstract methods cannot be called'; }}// 步槍class Rifle extends AbstractGun { shoot(){ console.log('步槍射擊...'); }}// 狙擊槍class AUG extends AbstractGun { shoot(){ console.log('AUG射擊...'); }}

從上面的代碼可以看出,步槍與狙擊槍的shoot全部都是依賴于AbstractGun抽象的槍類,上述編程滿足了依賴倒置原則。

接口隔離什么是接口隔離

接口隔離:客戶端不應(yīng)該依賴它不需要的接口;一個類對另一個類的依賴應(yīng)該建立在最小的接口上。(節(jié)選自百度百科)

接口隔離原則與單一職責(zé)原則的審視角度不相同。單一職責(zé)原則要求是類和接口的職責(zé)單一,注重的職責(zé),這是業(yè)務(wù)邏輯上的劃分。接口隔離原則要求接口的方法盡量少。

接口隔離好處 避免接口污染 提高靈活性 提供定制服務(wù) 實現(xiàn)高內(nèi)聚實例

function mix(...mixins) { class Mix {} for (let mixin of mixins) { copyProperties(Mix, mixin); copyProperties(Mix.prototype, mixin.prototype); } return Mix;}function copyProperties(target, source) { for (let key of Reflect.ownKeys(source)) { if ( key !== 'constructor'&& key !== 'prototype'&& key !== 'name') { let desc = Object.getOwnPropertyDescriptor(source, key); Object.defineProperty(target, key, desc); } }}class Behavior { eat(){ throw 'Abstract methods cannot be used'; } call(){ throw 'Abstract methods cannot be used'; }}class Action { climbTree(){ throw 'Abstract methods cannot be used'; }}class Dog extends Behavior{ eat(food){ console.log(`狗正在吃${food}`); } hungry(){ console.log('汪汪汪,我餓了') }}const CatMin = mix(Behavior,Action);class Cat extends CatMin{ eat(food){ console.log(`貓正在吃${food}`); } hungry(){ console.log('喵喵喵,我餓了') } climbTree(){ console.log('爬樹很開心哦~') }}let dog = new Dog();dog.eat('骨頭');dog.hungry();let cat = new Cat();cat.eat('魚');cat.hungry();cat.climbTree();

大家一定要好好分析一下上面的代碼,共有兩個抽象類,分別對應(yīng)不同的行為,Cat與Dog類擁有共同的行為,但是Cat又擁有其自己單獨的行為,使用抽象(即接口)繼承其方法,使用接口隔離使其完成各自的工作,各司其職。

迪米特法則

迪米特法則:最少知識原則(Least Knowledge Principle 簡寫LKP),就是說一個對象應(yīng)當(dāng)對其他對象有盡可能少的了解,不和陌生人說話。英文簡寫為: LoD.(節(jié)選自百度百科)

迪米特法則的做法觀念就是類間解耦,弱耦合,只有弱耦合了以后,類的復(fù)用率才可以提高。一個類應(yīng)該對其他對象保持最少的了解。通俗來講,就是一個類對自己依賴的類知道的越少越好。因為類與類之間的關(guān)系越密切,耦合度越大,當(dāng)一個類發(fā)生改變時,對另一個類的影響也越大。

迪米特法則好處 減少對象之間的耦合性實例

class ISystem { close(){ throw 'Abstract methods cannot be used'; }}class System extends ISystem{ saveCurrentTask(){ console.log('saveCurrentTask') } closeService(){ console.log('closeService') } closeScreen(){ console.log('closeScreen') } closePower(){ console.log('closePower') } close(){ this.saveCurrentTask(); this.closeService(); this.closeScreen(); this.closePower(); }}class IContainer{ sendCloseCommand(){ throw 'Abstract methods cannot be used'; }}class Container extends IContainer{ constructor(){ super() this.system = new System(); } sendCloseCommand(){ this.system.close(); }}class Person extends IContainer{ constructor(){ super(); this.container = new Container(); } clickCloseButton(){ this.container.sendCloseCommand(); }}let person = new Person();person.clickCloseButton();

上面代碼中Container作為媒介,其調(diào)用類不知道其內(nèi)部是如何實現(xiàn),用戶去觸發(fā)按鈕,Container把消息通知給計算機(jī),計算機(jī)去執(zhí)行相對應(yīng)的命令。

組合/聚合復(fù)用原則

聚合(Aggregation)表示一種弱的‘擁有’關(guān)系,體現(xiàn)的是A對象可以包含B對象但B對象不是A對象的一部分。

合成(Composition)則是一種強(qiáng)的’擁有’關(guān)系,體現(xiàn)了嚴(yán)格的部分和整體關(guān)系,部分和整體的生命周期一樣。

組合/聚合:是通過獲得其他對象的引用,在運行時刻動態(tài)定義的,也就是在一個對象中保存其他對象的屬性,這種方式要求對象有良好定義的接口,并且這個接口也不經(jīng)常發(fā)生改變,而且對象只能通過接口來訪問,這樣我們并不破壞封裝性,所以只要類型一致,運行時還可以通過一個對象替換另外一個對象。

優(yōu)先使用對象的合成/聚合將有助于你保持每個類被封裝,并被集中在單個任務(wù)上,這樣類和類繼承層次會保持較小規(guī)模,而且不太可能增長為不可控制的龐然大物。

組合/聚合復(fù)用原則好處 新的實現(xiàn)較為容易,因為超類的大部分功能可通過繼承關(guān)系自動進(jìn)入子類; 修改或擴(kuò)展繼承而來的實現(xiàn)較為容易。實例

function mix(...mixins) { class Mix {} for (let mixin of mixins) { copyProperties(Mix, mixin); copyProperties(Mix.prototype, mixin.prototype); } return Mix;}function copyProperties(target, source) { for (let key of Reflect.ownKeys(source)) { if ( key !== 'constructor'&& key !== 'prototype'&& key !== 'name') { let desc = Object.getOwnPropertyDescriptor(source, key); Object.defineProperty(target, key, desc); } }}class Savings { saveMoney(){ console.log('存錢'); } withdrawMoney(){ console.log('取錢'); }}class Credit { overdraft(){ console.log('透支') }}const CarMin = mix(Savings,Credit);class UserCar extends CarMin { constructor(num,carUserName){ super(); console.log() this.carNum = num; this.carUserName = carUserName; } getCarNum(){ return this.carNum; } getCarUserName(){ return this.carUserName; }}let myCar = new UserCar(123456798,'Aaron');console.log(myCar.getCarNum());console.log(myCar.getCarUserName());myCar.saveMoney();myCar.withdrawMoney();myCar.overdraft();總結(jié)

這些原則在設(shè)計模式中體現(xiàn)的淋淋盡致,設(shè)計模式就是實現(xiàn)了這些原則,從而達(dá)到了代碼復(fù)用、增強(qiáng)了系統(tǒng)的擴(kuò)展性。所以設(shè)計模式被很多人奉為經(jīng)典。我們可以通過好好的研究設(shè)計模式,來慢慢的體會這些設(shè)計原則。

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》

希望本文所述對大家JavaScript程序設(shè)計有所幫助。

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲高清成人| 国产高清视频一区二区| 成人羞羞视频在线看网址| 国产一区福利| 三级在线看中文字幕完整版| 亚洲国产福利| 成人日韩在线观看| 国内精品福利| 视频一区视频二区中文字幕| 中文字幕一区二区三区在线视频| 亚洲精品无播放器在线播放| 视频一区中文字幕| 久久狠狠久久| 深夜福利视频一区二区| 午夜久久黄色| 婷婷精品久久久久久久久久不卡| 国产精品久久久久av蜜臀| 精品国产免费人成网站| 欧美日韩一二三四| 亚洲三级精品| 精品伊人久久久| 日韩精品水蜜桃| 噜噜噜久久亚洲精品国产品小说| 日韩欧美三区| 久久亚洲资源中文字| 人人香蕉久久| 亚洲在线国产日韩欧美| 91麻豆精品激情在线观看最新| 国产一区二区视频在线看| 蜜桃成人av| 久久精品72免费观看| sm捆绑调教国产免费网站在线观看| 免费欧美一区| 日韩av二区在线播放| 国产理论在线| 中文视频一区| 国产成人精品一区二区免费看京 | 日本成人在线网站| 欧美国产极品| 黄色成人在线网址| 国产精品最新自拍| 伊人久久大香线蕉av不卡| 日韩精彩视频在线观看| 亚洲欧洲高清| 综合亚洲色图| 国产成人免费视频网站视频社区| 波多野结衣一区| 国产一卡不卡| 亚洲精品成人| 麻豆精品一区二区综合av| re久久精品视频| 国产精品亚洲二区| 亚洲电影在线| 欧美日韩调教| 午夜久久久久| 国产一区二区三区不卡视频网站| 免费在线观看日韩欧美| 日韩电影在线视频| 国产探花一区| 美女尤物久久精品| 亚洲播播91| 国产精品最新| 国产婷婷精品| 日韩国产欧美| 久久狠狠久久| 六月婷婷一区| 高清日韩中文字幕| 深夜福利一区| 激情综合网五月| 国产在线一区不卡| 日本成人在线一区| 国产亚洲在线观看| 日韩精品免费一区二区三区| 国产精品v亚洲精品v日韩精品| 首页国产欧美久久| 热三久草你在线| 国产精品探花在线观看| 天堂va蜜桃一区二区三区| 亚洲成人av观看| 国产精品啊啊啊| 日本成人在线一区| 亚洲制服少妇| 久久精品卡一| 高潮一区二区| 精品日本视频| 清纯唯美亚洲综合一区| 在线亚洲观看| 欧美国产91| 日韩国产网站| 成人日韩精品| 日韩高清欧美| 日本一区二区高清不卡| 国产精品久久久久久久久久齐齐 | 丝袜亚洲精品中文字幕一区| 欧美aa在线观看| 久久精品国产精品亚洲毛片| 亚洲a级精品| 日韩精品一级中文字幕精品视频免费观看 | 青青青免费在线视频| 国产欧美日韩免费观看| 日本aⅴ精品一区二区三区| 免费精品视频| 亚洲专区欧美专区| 亚洲精品中文字幕乱码| 久久中文字幕av一区二区不卡| 蜜臀久久精品| 精品国模一区二区三区| 日韩在线观看| 中文av在线全新| 欧美日韩视频网站| 精品亚洲美女网站| 日韩毛片视频| 99视频精品全部免费在线视频| 夜鲁夜鲁夜鲁视频在线播放| 精品精品国产三级a∨在线| av不卡在线| 在线人成日本视频| 亚洲精品护士| 亚州av乱码久久精品蜜桃| 色婷婷色综合| 国产精品s色| 婷婷成人av| 国产精品毛片一区二区三区| 日本美女一区| 日韩av一区二区在线影视| 亚洲人www| 蜜桃一区二区三区在线| 亚洲精品黄色| 97精品资源在线观看| 亚洲综合婷婷| 91精品国产一区二区在线观看| 欧美一级网站| 麻豆精品少妇| zzzwww在线看片免费| 欧美sss在线视频| 亚洲精品99| 亚洲精品乱码久久久久久蜜桃麻豆| 综合亚洲视频| 欧美日韩a区| 精品国产乱码久久久久久1区2匹| 超碰在线99| 婷婷激情图片久久| 视频精品一区二区| 欧美日韩精品一区二区三区视频 | 制服诱惑一区二区| 亚洲一区日韩在线| 视频一区日韩精品| 国产欧美另类| 欧美国产小视频| 亚洲国产日韩欧美在线| 伊人精品久久| 久久av超碰| 欧美综合另类| 日韩毛片网站| 国产欧美激情| 波多视频一区| 最新亚洲一区| 国产一卡不卡| 天堂网av成人| 六月丁香综合| 国产美女高潮在线| 日产欧产美韩系列久久99| 日韩三区在线| 国产精品多人| 噜噜噜久久亚洲精品国产品小说| 精品免费av一区二区三区| 石原莉奈一区二区三区在线观看| 国产一区二区三区四区| 亚洲精品护士| 欧美黄色网页| 国产精品第十页| 首页国产欧美日韩丝袜| 97精品视频在线看| 日韩精品久久久久久久软件91| 99久久99久久精品国产片果冰| 国产日韩欧美| 久久福利一区| 日韩成人综合| 国产精品久久| 亚洲精品三级| 99热免费精品| 欧洲精品一区二区三区| 国产精品久久久久久久久久白浆| 亚洲一区二区三区高清不卡| 国语精品一区| 日韩av网站在线免费观看| 亚洲视频播放| 午夜影院一区| 麻豆高清免费国产一区| 午夜性色一区二区三区免费视频| 免费国产自久久久久三四区久久 | 视频一区在线播放| 久久国产中文字幕| 精品九九久久| 婷婷精品在线| 国产视频一区在线观看一区免费| 亚洲精品在线影院| 国产一区二区三区四区| 国产精品一二| 国产亚洲精品精品国产亚洲综合 |