摘要:如果非要重寫父類的方法,比較通用的做法是原來的父類和子類都繼承一個(gè)更通俗的基類,原有的繼承關(guān)系去掉,采用依賴聚合,組合等關(guān)系代替。里氏替換原則通俗的來講就是子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。一有限狀態(tài)機(jī)狀態(tài)總數(shù)是有限的。
設(shè)計(jì)模式 抽象類 抽象類的表現(xiàn)
不能被實(shí)例,只能被繼承
最少有一個(gè)抽象方法(多態(tài)的具體體現(xiàn))
// 汽車抽象類,當(dāng)使用其實(shí)例對象的方法時(shí)會拋出錯(cuò)誤 var Car = function() {}; Car.prototype = { getPrice: function() { return new Error("抽象方法getPrice不能調(diào)用。"); }, getSpeed: function() { return new Error("抽象方法getSpeed不能調(diào)用。"); } };
上面Car類其實(shí)什么都沒有做,但用原型的方法還會直接報(bào)錯(cuò),這一特點(diǎn)非常有必要,因?yàn)榭倳幸恍┳宇惾ダ^承父類,這些父類經(jīng)常會去定義一些必要的方法,卻沒有具體的實(shí)現(xiàn).
一旦子類創(chuàng)建了一個(gè)對象,但是子類沒有重寫父類的方法而被調(diào)用,就會直接報(bào)錯(cuò),這個(gè)對大型項(xiàng)目中對子類的約束是非常有必要的,代碼頁更加清晰
單一職責(zé)原則...里氏替換原則
子類可以實(shí)現(xiàn)父類的抽象方法,但是不能覆蓋父類的非抽象方法
繼承作為面向?qū)ο笕筇匦灾唬诮o程序設(shè)計(jì)帶來巨大便利的同時(shí),也帶來了弊端。比如使用繼承會給程序帶來侵入性,程序的可移植性降低,增加了對象間的耦合性,如果一個(gè)類被其他的類所繼承,則當(dāng)這個(gè)類需要修改時(shí),必須考慮到所有的子類,并且父類修改后,所有涉及到子類的功能都有可能會產(chǎn)生故障。
function Foo(){ this.aa="sdf"; } Foo.prototype.func1 = function(a,b){ return a-b; }; function Sub(){ } Sub.prototype = new Foo(); var demo = new Sub(); console.log("100-50="+demo.func1(100,50)); //運(yùn)行結(jié)果: //100-50=50 //后來,我們需要增加一個(gè)新的功能:完成兩數(shù)相加,然后再與100求和,由類B來負(fù)責(zé)。即類B需要完成兩個(gè)功能: function Sub1 (){ } Sub1.prototype = new Foo(); Sub1.prototype.func1 = function(a,b){ return a+b; }; Sub1.prototype.func2 = function(a,b){ return this.func1(a,b)+100; }; var demo1 = new Sub1(); console.log("100-50="+demo1.func2(100,50)) //運(yùn)行結(jié)果: //100-50=250
我們發(fā)現(xiàn)原本運(yùn)行正常的相減功能發(fā)生了錯(cuò)誤。原因就是類Sub1在給方法起名時(shí)無意中重寫了父類的方法,造成所有運(yùn)行相減功能的代碼全部調(diào)用了類Sub1重寫后的方法,造成原本運(yùn)行正常的功能出現(xiàn)了錯(cuò)誤。在本例中,引用基類Foo完成的功能,換成子類Sub1之后,發(fā)生了異常。在實(shí)際編程中,我們常常會通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個(gè)繼承體系的可復(fù)用性會比較差,特別是運(yùn)用多態(tài)比較頻繁時(shí),程序運(yùn)行出錯(cuò)的幾率非常大。如果非要重寫父類的方法,比較通用的做法是:原來的父類和子類都繼承一個(gè)更通俗的基類,原有的繼承關(guān)系去掉,采用依賴、聚合,組合等關(guān)系代替。開閉原則里氏替換原則通俗的來講就是:子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。它包含以下4層含義:
子類可以實(shí)現(xiàn)父類的抽象方法,但不能覆蓋父類的非抽象方法。
子類中可以增加自己特有的方法。
當(dāng)子類的方法重載父類的方法時(shí),方法的前置條件(即方法的形參)要比父類方法的輸入?yún)?shù)更寬松。
當(dāng)子類的方法實(shí)現(xiàn)父類的抽象方法時(shí),方法的后置條件(即方法的返回值)要比父類更嚴(yán)格。
看上去很不可思議,因?yàn)槲覀儠l(fā)現(xiàn)在自己編程中常常會違反里氏替換原則,程序照樣跑的好好的。所以大家都會產(chǎn)生這樣的疑問,假如我非要不遵循里氏替換原則會有什么后果?
后果就是:你寫的代碼出問題的幾率將會大大增加。參考文檔:http://blog.csdn.net/zhengzhb...
function Foo(){ } Foo.prototype.getPerson = function(name){ if(name==="tom"){ return { name:"tom", age:"20" } }else if(name==="jack"){ return { name:"tom", age:"20", sex:"boy" } } } console.log(new Foo().getPerson("tom")); //這個(gè)時(shí)候 如果我要獲取名為lily這個(gè)人的屬性,就需要更改getPerson,這樣所有調(diào)用該接口的對象都會受到影響,這個(gè)時(shí)候我們?nèi)绾蝸碇貥?gòu) function Foo(){ } Foo.prototype.personInfo = function(){};//寫一個(gè)抽象方法 Foo.prototype.getPerson = function(){ return this.personInfo(); }; var a = new Foo(); a.personInfo=function(){ return { name:"lily", age:20, sex:"girl" } }; console.log(a.getPerson());狀態(tài)模式
狀態(tài)模式(State)允許一個(gè)對象在其內(nèi)部狀態(tài)改變的時(shí)候改變它的行為,對象看起來似乎修改了它的類。狀態(tài)模式的使用場景也特別明確,有如下兩點(diǎn):
一個(gè)對象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。(有些對象通常會有好幾個(gè)狀態(tài),在每個(gè)狀態(tài)都只可以做當(dāng)前狀態(tài)才可以做的事情,而不能做其它狀態(tài)能做的事兒)
一個(gè)操作中含有大量的分支語句,而且這些分支語句依賴于該對象的狀態(tài)。狀態(tài)通常為一個(gè)或多個(gè)枚舉常量的表示。
一、有限狀態(tài)機(jī)
狀態(tài)總數(shù)(state)是有限的。
任一時(shí)刻,只處在一種狀態(tài)之中。
某種條件下,會從一種狀態(tài)轉(zhuǎn)變(transition)到另一種狀態(tài)。
// 狀態(tài)機(jī) var FSM = { off: { buttonWasPressed: function() { console.log("關(guān)燈"); this.button.innerHTML = "下一次按我是開燈"; // 這是Light上的屬性!!! this.currState = FSM.on; // 這是Light上的屬性!!! } }, on: { buttonWasPressed: function() { console.log("開燈"); this.button.innerHTML = "下一次按我是關(guān)燈"; this.currState = FSM.off; } }, }; var Light = function() { this.currState = FSM.off; // 設(shè)置當(dāng)前狀態(tài) this.button = null; }; Light.prototype.init = function() { var button = document.createElement("button"); self = this; button.innerHTML = "已關(guān)燈"; this.button = document.body.appendChild(button); this.button.onclick = function() { // 請求委托給FSM狀態(tài)機(jī) self.currState.buttonWasPressed.call(self); } } var light = new Light(); light.init();
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95708.html
摘要:設(shè)計(jì)模式與開發(fā)實(shí)踐讀書筆記最近利用碎片時(shí)間在上面閱讀設(shè)計(jì)模式與開發(fā)實(shí)踐讀書這本書,剛開始閱讀前兩章內(nèi)容,和大家分享下我覺得可以在項(xiàng)目中用的上的一些筆記。事件綁定暫時(shí)這么多,以后會不定期更新一些關(guān)于我讀這本書的筆記內(nèi)容 JavaScript 設(shè)計(jì)模式與開發(fā)實(shí)踐讀書筆記 最近利用碎片時(shí)間在 Kindle 上面閱讀《JavaScript 設(shè)計(jì)模式與開發(fā)實(shí)踐讀書》這本書,剛開始閱讀前兩章內(nèi)容,...
摘要:保護(hù)代理和虛擬代理保護(hù)代理當(dāng)有許多需求要向某對象發(fā)出一些請求時(shí),可以設(shè)置保護(hù)代理,通過一些條件判斷對請求進(jìn)行過濾。虛擬代理在程序中可以能有一些代價(jià)昂貴的操作。而虛擬代理是最常用的一種代理模式。 代理模式 代理模式是為一個(gè)對象提供一個(gè)代用品或占位符,以便控制對它的訪問。 保護(hù)代理和虛擬代理 保護(hù)代理:當(dāng)有許多需求要向某對象發(fā)出一些請求時(shí),可以設(shè)置保護(hù)代理,通過一些條件判斷對請求進(jìn)行過濾。...
摘要:模式閱讀筆記第一部分函數(shù)模式總的來說模式是一本力薦的進(jìn)階書書里面涉及了很多在學(xué)習(xí)過程中會碰到的坑然后提供了很不錯(cuò)的解決方法雖然很多人吐槽這本書的翻譯但是糟糕的翻譯還是無法掩蓋這是一本好書的事實(shí)因此這里我會結(jié)合書上的知識和我的理解來寫一些 Javascript模式 閱讀筆記-第一部分-函數(shù)模式 總的來說,javascript模式是一本力薦的js進(jìn)階書,書里面涉及了很多在學(xué)習(xí)javascr...
摘要:探討判斷橫豎屏的最佳實(shí)現(xiàn)前端掘金在移動端,判斷橫豎屏的場景并不少見,比如根據(jù)橫豎屏以不同的樣式來適配,抑或是提醒用戶切換為豎屏以保持良好的用戶體驗(yàn)。 探討判斷橫豎屏的最佳實(shí)現(xiàn) - 前端 - 掘金在移動端,判斷橫豎屏的場景并不少見,比如根據(jù)橫豎屏以不同的樣式來適配,抑或是提醒用戶切換為豎屏以保持良好的用戶體驗(yàn)。 判斷橫豎屏的實(shí)現(xiàn)方法多種多樣,本文就此來探討下目前有哪些實(shí)現(xiàn)方法以及其中的優(yōu)...
摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當(dāng)我們在程序中創(chuàng)建一個(gè)對象時(shí),這個(gè)對象將被保存到運(yùn)行時(shí)數(shù)據(jù)區(qū)中,以便反復(fù)利用因?yàn)閷ο蟮膭?chuàng)建成本通常較大,這個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)就是堆內(nèi)存。 上一篇:《javascript高級程序設(shè)計(jì)》筆記:繼承近幾篇博客都會圍繞著圖中的知識點(diǎn)展開 showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...
摘要:策略模式可以避免代碼中的多重判斷條件。策略模式在程序中或多或少的增加了策略類。此文僅記錄本人閱讀設(shè)計(jì)模式與開發(fā)實(shí)踐這個(gè)本時(shí)的感受,感謝作者曾探寫出這么好的一本書。設(shè)計(jì)模式中很重要的一點(diǎn)就是將不變和變分離出來。參考設(shè)計(jì)模式與開發(fā)實(shí)踐曾探 策略模式的定義是:定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且是它們可以相互替換。 策略模式可以避免代碼中的多重判斷條件。 策略模式很好的體現(xiàn)了開放-...
閱讀 2416·2021-11-18 10:02
閱讀 1929·2021-10-13 09:40
閱讀 3008·2021-09-07 10:07
閱讀 2117·2021-09-04 16:48
閱讀 1015·2019-08-30 13:18
閱讀 2462·2019-08-29 14:03
閱讀 2929·2019-08-29 12:54
閱讀 3167·2019-08-26 11:41