摘要:為什么要學習設計模式做事情之前問個為什么總是好的。設計模式的使用方法關于使用方式,像我這種初學者最容易犯的錯誤就是生搬硬套,但是模仿本來也是學習的一個過程,最重要的事情是在模仿中要學會思考。
為什么要學習設計模式?
做事情之前問個為什么總是好的。關于設計模式的好壞,我在知乎上也看過一些討論,有知友對其提出過一些疑問,里面有一些關于設計模式的觀點:
設計模式有何不妥,所謂的荼毒體現在哪?
設計模式是不是有點太玄了?
任何事物的出現都有其道理,任何語言都有其不足之處,設計模式是對語言不足的補充(Peter Norvig)。設計模式也是編程經驗的總結,我想學習它對像我這樣的前端新手的能力會有很大的提升。
使用設計模式的好處《Head First 設計模式》一書舉了一個非常有意思的例子:
兩個人點餐,一個人說:“我要一份涂了奶酪及果醬的白面包,加了香草冰淇淋的巧克力汽水..”;
另外一個人說:“給我一份C.J懷特,一個黑與白”。
表達同樣的意思,效果卻完全不同,這里就說到一個比較大的概念“共享詞匯”。
共享詞匯就是一組概念,行為,方法等等的集合,這個在任何行業(yè)都有用,就像中文菜名“回鍋肉”,廚子知道什么是回鍋肉,你也知道什么是回鍋肉,如果沒有回鍋肉這個共享詞匯,我好像真的想不到一個合適的描述來點這道菜。
回到設計模式,各種設計模式就是一個個的共享詞匯,它不僅僅是一個名稱,更是一整套模式背后所象征的質量,特征,約束。
細說說它的好處:
設計模式能讓你用更少的詞匯做更充分的溝通;
談話在模式層次時,不會被壓低到對象和類這種瑣碎的事情上;
懂設計模式的團隊,彼此之間對于設計的看法不容易產生誤解;
共享詞匯能幫助初級人員快速成長。
總結一下設計模式的作用:
設計模式的使用方法幫助我們將應用組織成容易了解,容易維護,具有彈性的架構,建立可維護的OO系統(tǒng),要訣在于隨時想到系統(tǒng)以后可能需要的變化以及應付變化的原則。
關于使用方式,像我這種初學者最容易犯的錯誤就是生搬硬套,但是模仿本來也是學習的一個過程,最重要的事情是在模仿中要學會思考。我也是設計模式的初學者,所以我會常用這句話來提醒自己,看過一句關于如何最好的使用設計模式的話:
“把模式裝進腦子里,然后在你的設計和已有的應用中,尋找何處可以使用它們”。
這就有點像是張無忌練習太極拳了,忘了所有的模式吧,你已經在潛移默化的使用它了。當然如果你不學設計模式,你可能也在無意識的使用一些設計模式了,但是這個在跟學過以后再無意識的使用設計模式,應該隔著兩重境界吧。
當然要達到這個境界,少不了大量的練習,當然也不能忘了設計是一門藝術,總有許多可取舍的地方。
設計模式的一些原則找出應用中可能需要改變之處,把它們獨立出來,不要和哪些不需要改變的代碼混在一起(低耦合);
針對接口編程,而不是針對實現編程;
關鍵在于多態(tài),程序可以針對超類型編程,執(zhí)行時會根據實際狀況執(zhí)行到真正的行為,不會被綁死在超類型的行為上(在JavaScript中并沒有超類型的概念。)我的理解是,接口可以理解為一個動作,而動作的具體實現則不用確定。這一點在下文講解多態(tài)時會有一個更加具體的例子。
多用組合,少用繼承
可能還有一些其它的原則,目前,我還沒有涉及到,在之后的學習過程中,再補充。
需要了解的一些其它概念要真正的理解設計模式,需要了解面向對象的一些基礎概念:抽象,多態(tài),封裝和繼承。
就JavaScript而言,由于是一門動態(tài)語言,在此不考慮抽象這一概念。
概念:同一操作作用于不同的對象上時,可以產生不同的解釋和不同的執(zhí)行結果。
比如說有兩只動物,雞和鴨,當發(fā)出命令“叫”時,雞會“咯咯咯“,鴨會”嘎嘎嘎“;
多態(tài)背后的思想是將“做什么”和“誰去做以及怎么去做”分離開來,也就是將“不變的事”和“可變的事物”分離開來。
多態(tài)的實現:歸根到底是要消除類型之間的耦合關系,JS的變量類型在運行時是可變的,這意味著JS對象的多態(tài)性是與生俱來的。
多態(tài)的作用:通過把過程化的條件分支語句轉化為對象的多態(tài)性,從而消除這些條件分支語句。
看一個例子來理解多態(tài):
// 只使用谷歌地圖 var googleMap = { show: function() { console.log("開始渲染谷歌地圖"); } }; var renderMap = function() { googleMap.show(); }; renderMap(); //輸出:開始渲染谷歌地圖 // 好吧,谷歌在某些地方不好用,在某些要換成百度地圖了, var googleMap = { show: function() { console.log("開始渲染谷歌地圖"); } }; var baiduMap = { show: function() { console.log("開始渲染百度地圖"); } }; var renderMap = function(type) { if (type === "google") { googleMap.show(); } else if (type = "baidu") { baiduMap.show(); }; }; renderMap("google"); //輸出:開始渲染谷歌地圖 renderMap("baidu"); //輸出:開始渲染百度地圖 // 上述代碼有一點的彈性,但是如果在更換地圖,改變的地方太多了,這里就可以運用多態(tài)性這個理念了,這里也把做什么和怎么做分開了 // 抽象出相同部分,條件分支語句轉化為對象的多態(tài)性 var renderMap = function(map){ //做什么 if (map.show() instanceof Function) { map.show(); } }; renderMap("google"); //輸出:開始渲染谷歌地圖 renderMap("baidu"); //輸出:開始渲染百度地圖 // 再添加一個搜搜地圖 var sosoMap = { // 怎么做 show: function() { console.log("開始渲染搜搜地圖"); } }; renderMap("soso"); //輸出:開始渲染搜搜地圖 // 本例來自于《JavaScript設計模式與開發(fā)實踐》封裝
封裝的目的是將信息隱藏,包括隱藏數據,隱藏實現細節(jié),設計細節(jié)以及隱藏對象的類型等。
封裝分為四類:封裝數據,封裝實現,封裝類型和封裝變化
封裝數據:
在許多面相對象系統(tǒng)中,封裝數據是由語法解析來實現的(private public proctected);
JavaScript中沒有對這些變量的支持,只能利用變量的作用域來實現封裝,只能模擬出 public、private 兩種封裝性。(ES6可用let),一般用函數來創(chuàng)建作用域。
封裝實現:
使得對象內部的變化對其他對象而言是不可見的,對象對其自己的行為負責,使得對象之間的耦合變得松散,對象之間只通過暴露API接口來通信,修改一個對象時,可以隨意地修改它的內部實現,只要對外的接口沒有變化,就不會影響到程序的其它功能。
封裝類型:
對靜態(tài)語言而言,是一種重要的封裝方式,把對象的真正類型隱藏在抽象類或者接口之后,Javascript沒有這方面的支持,因此也沒有這方面的需要;
封裝變化:
把系統(tǒng)中穩(wěn)定不變的部分和容易變化的部分隔離開來,在系統(tǒng)的演變過程中,我們只需要替換那些容易變化的部分,如果這些部分是已經封裝好的,替換起來也相對容易,這可以最大程度的保證程序的穩(wěn)定性和可擴展性
繼承說到繼承,JavaScript最重要的概念可能在于原型鏈。
基于原型鏈的委托機制就是原型繼承的本質。
所有的數據都是對象,JS的根對象是Object.prototype對象,它是一個空對象;
要得到一個對象,不是通過實例化類而是找到一個對象作為原型來克隆它;
對象會記住它的原型;就JS而言,對象的原型其實是其構造器的原型(new),包含在其隱藏屬性_proto_中;
如果對象無法響應某個請求,它會把這個請求委托給自己的原型。
JavaScript的原型最初都是由Object.prototype對象克隆而來;
對象構造器的原型并不限于Object.prototype,可以動態(tài)的指向其他對象; A.prototype=obj
原型鏈并非無限長,到頂(Object.prototype)以后,如果沒有找到就會返回undefined;
本文是我學習設計模式的第一篇筆記,里面若有不恰當的地方,歡迎隨時指出,也希望您看完本文,跟我一樣有所收獲。
參考書籍
Head First 設計模式
JavaScript設計模式與開發(fā)實踐
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/86348.html
摘要:如果看視頻能夠成為高手,那每一個球迷都應該是梅西??朔睦碚系K前端的飛速發(fā)展,不僅僅是初學者,哪怕熟手都會焦慮感覺很多東西都不會。 很多前端都想找一個學習計劃,然后認真學,成為一個大牛;他們迫切的想知道自己該學什么,然后看什么書,有什么資源可以用! 我今天要告訴你的是,你不要看什么書,不要做什么事!因為如果你再不恰當的階段,看了那些看起來很正確的金科玉律一般的書籍,除了打消你學習的興趣...
摘要:問題回答者黃軼,目前就職于公司擔任前端架構師,曾就職于滴滴和百度,畢業(yè)于北京科技大學。最后附上鏈接問題我目前是一名后端工程師,工作快五年了。 showImg(https://segmentfault.com/img/bVbuaiP?w=1240&h=620); 問題回答者:黃軼,目前就職于 Zoom 公司擔任前端架構師,曾就職于滴滴和百度,畢業(yè)于北京科技大學。 1. 前端開發(fā) 問題 大...
摘要:先說下我面試情況,我一共面試了家公司。篇在我面試的眾多公司里,只有同城的面問到相關問題,其他公司壓根沒問。我自己回答的是自己開發(fā)組件面臨的問題。完全不用擔心對方到時候打電話核對的問題。 2019的5月9號,離發(fā)工資還有1天的時候,我的領導親切把我叫到辦公室跟我說:阿郭,我們公司要倒閉了,錢是沒有的啦,為了不耽誤你,你趕緊出去找工作吧。聽到這話,我虎軀一震,這已經是第2個月沒工資了。 公...
摘要:昨天在我在國外網站上看到一篇文章,作者分享了他自學編程個月后找到工作的經歷。而本文中,我主要針對想要通過學習編程找工作的角度來談。我在年月犯了一個錯誤我認為首要任務是找到一份前端開發(fā)的工作。 昨天在我在國外網站 reddit 上看到一篇文章,作者分享了他 自學編程 9 個月后找到工作 的經歷。文章不到一天就得到3千多贊,2百條回復。我看了下內容,非常中肯,其中有不少建議也是我在編程教室...
摘要:對于學習,工作或者技術群聊里面的一些陌生的詞匯,不懂的地方,要時常抱著一顆好奇心去看待,每天花一分鐘把這些出現的詞記在備忘錄上,等積累到十條以上的時候,就可以找個統(tǒng)一的時間來百度,利用網絡工具,查找資料,一一逐步了解,排查。 認真苦干的態(tài)度 最基本的態(tài)度,不多說,每個職場人都應該做到的。 老板招聘一個員工,無論是面試還是復試,都會多方位的考驗這個態(tài)度,如果沒有把工作當做一件神圣的事情來...
閱讀 3614·2020-12-03 17:42
閱讀 2780·2019-08-30 15:54
閱讀 2241·2019-08-30 15:44
閱讀 585·2019-08-30 14:08
閱讀 983·2019-08-30 14:00
閱讀 1118·2019-08-30 13:46
閱讀 2801·2019-08-29 18:33
閱讀 2951·2019-08-29 14:11