【D1n910】第 21 章 命令模式 《JavaScript 設(shè)計模式》
正常操作,正常分析,大家好,我是D1n910。
今天我繼續(xù)來學(xué)習(xí) 《JavaScript 設(shè)計模式》的第四篇 行為型設(shè)計模式
這是一個連續(xù)的讀書筆記,所以如果你之前的內(nèi)容沒有看的話,可以去看看(建議直接看書,當(dāng)然書的例子都比較早了,是2015年之前的代碼內(nèi)容,過了六年了,前端發(fā)展了很多,比如類的聲明可以直接用 Class 了)。
直接查看目錄就可以查看到所有的系列文章啦。

這里再次感謝 《Javascript 設(shè)計模式》及其作者 張榮銘,專欄內(nèi)容是在它的基礎(chǔ)上生成的。
現(xiàn)在會覺得很多設(shè)計模式離我們有點遙遠(yuǎn),是因為我們現(xiàn)在都在用大佬寫好的框架吧,很多設(shè)計模式都包含在框架里了。
后面有機會的話,我希望我可以查看目前主流框架的源代碼,然后進(jìn)行講解。
對應(yīng)的代碼,請查看
https://github.com/D1N910/JavaScript-design-patterns.git

第四篇 行為型設(shè)計模式
行為型設(shè)計模式用于不同對象之間職責(zé)劃分或算法抽象,行為型設(shè)計模式不僅僅涉及類和對象,還涉及類或?qū)ο笾g的交流模式并加以實現(xiàn)。
第 21?章? 命令模式
命令模式(Command):將請求與實現(xiàn)解耦并封裝成獨立對象,從而使不同的請求對客戶端實現(xiàn)參數(shù)化。一般是用于創(chuàng)建多個類似的視圖。
比如我們的場景是能夠動態(tài)創(chuàng)建一個圖片展示頁面,其中具有標(biāo)題,圖片容器。
創(chuàng)建命令對象
1、命令對象結(jié)構(gòu):

2、書寫基本靜態(tài)變量
? ?// 模塊
? ?var tpl = {
? ? ? ?// 展示標(biāo)題結(jié)構(gòu)模版
? ? ? ?title: [
? ? ? ? ? ?'<div class="title">',
? ? ? ? ? ? ? ?'<div class="main">',
? ? ? ? ? ? ? ? ? ?'<h2>{ #title# }</h2>',
? ? ? ? ? ? ? ? ? ?'<p>{ #tips# }</p>',
? ? ? ? ? ? ? ?'</div>',
? ? ? ? ? ?'</div>'
? ? ? ?].join(),
? ? ? ?// 展示圖片
? ? ? ?product: [
? ? ? ? ? ?'<div class="product">',
? ? ? ? ? ? ? ?'<img src="{ #src# }" alt="">',
? ? ? ? ? ? ? ?'<p>{ #text# }</p>',
? ? ? ? ? ?'</div>'
? ? ? ?].join()
? ?},
? ?// 緩存格式化內(nèi)容
? ?html = '';
? ?// 格式化字符串
? ?function ?formateString(str, obj) {
? ? ? ?// 替換'{ #' 與'# }' 之間的字符串
? ? ? ?return str.replace(/\{ #(\w+)# \}/g, function (match, key) {
? ? ? ? ? ?return obj[key]
? ? ? ?})
? ?}
格式化字符串的正則表達(dá)式很美妙,其中\(zhòng)w可以匹配正常的英文字符、數(shù)字、下劃線、橫杠,符合變量的規(guī)則;全局匹配后,能夠插入變量,真的非常美妙。
? ? ? ?// 創(chuàng)建方法
? ? ? ?create: function (data, type) {
? ? ? ? ? ?// 遍歷數(shù)組
? ? ? ? ? ?if (data.length) {
? ? ? ? ? ? ? ?for (var i = 0; i < data.length; i ++) {
? ? ? ? ? ? ? ? ? ?html += formateString(tpl[type], data)
? ? ? ? ? ? ? ?}
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?// 直接格式化
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?// 展示視圖
? ? ? ?dispaly: function (container, data, view) {
? ? ? ? ? ?// 如果傳入數(shù)據(jù)
? ? ? ? ? ?if (data) {
? ? ? ? ? ? ? ?this.create(data, view);
? ? ? ? ? ?}
? ? ? ? ? ?// 展示模塊
? ? ? ? ? ?container.innerHTML = html;
? ? ? ? ? ?html = '';
? ? ? ?}
? ?return function excute(msg) {
? ? ? ?// 解析命令,如果 msg 的 params 不是數(shù)組,要轉(zhuǎn)轉(zhuǎn)換成數(shù)組
? ? ? ?msg.params = Object.prototype.toString.call(msg.param) === "[object Array]" ? msg.param : [msg.param];
? ? ? ?Action[msg.command].apply(Action, msg.param)
? ?}
我們通過命令接口來使用 Action 方法,其中 apply 會重新定義 this,這里為了this指向為 Action,所以重新綁定了 Action,apply 的傳參是數(shù)組,所以這邊要轉(zhuǎn)換成數(shù)組。
6、使用命令。


命令模式封裝了執(zhí)行命令,解決命令發(fā)起者與命令執(zhí)行者之間的耦合。
每一條命令實質(zhì)上是一個操作。命令的使用者不必了解命令的執(zhí)行者(命令對象)的命令接口是如何實現(xiàn)的、命令是如何執(zhí)行的。所有的命令都存儲在命令對象中。
優(yōu)點:
解決命令使用者之間的耦合。新的命令很容易加入到命令系統(tǒng)中,供使用者使用。命令的使用具有一致性,多數(shù)的命令在一定成都上是簡化操作方法的使用的。
缺點:
每次執(zhí)行一次操作都要調(diào)用一次命令對象,增加了系統(tǒng)的復(fù)雜度。
本章 End
d1n910 于 2021年03月01日 寫于南山后海