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