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

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

第四篇 行為型設(shè)計(jì)模式
行為型設(shè)計(jì)模式用于不同對象之間職責(zé)劃分或算法抽象,行為型設(shè)計(jì)模式不僅僅涉及類和對象,還涉及類或?qū)ο笾g的交流模式并加以實(shí)現(xiàn)。
第 16 章 照貓畫虎 —— 模版方法模式
模版方法模式(Template Method): 父類中定義一組操作算法骨架,而將一些實(shí)現(xiàn)步驟推遲到子類中,使得子類可以不改變父類的算法結(jié)構(gòu)的同時可重新定義算法中某些實(shí)現(xiàn)步驟。
16.1、提示框歸一化(P110)
書中給出的場景是項(xiàng)目里的提示框因?yàn)槭遣煌娜藢懙?,代碼結(jié)構(gòu)乃至最終樣式都不太一樣,希望能夠把這些提示框進(jìn)行統(tǒng)一。
這些提示框有
普通提示框,只有確認(rèn)按鈕;
操作提示框,有確認(rèn)、取消按鈕;
16.2、美味的蛋糕(P111)
像做蛋糕一樣,每一個蛋糕造型不一樣,但是它們的模版可以是一樣的,都是圓柱體的蛋糕。
模版方法模式也是這樣,先創(chuàng)造一個基礎(chǔ)模版,然后再在這個基礎(chǔ)模版上去繼承改造。
16.3、創(chuàng)建基本提示框(P111)?16.4、模版原型方法(P112)
下面的開始用 ES6 類的寫法~
class Alert {
constructor(data) {
? ? ? ?if (!data) {
? ? ? ? ? ?return;
? ? ? ?}
? ? ? ?// 設(shè)置內(nèi)容
? ? ? ?this.content = data.content;
? ? ? ?// 創(chuàng)建提示框面板
? ? ? ?this.panel = document.createElement('div');
? ? ? ?// 創(chuàng)建提示內(nèi)容組件
? ? ? ?this.contentNode = document.createElement('p');
? ? ? ?// 創(chuàng)建確定按鈕組件
? ? ? ?this.confirmBtn = document.createElement('div');
? ? ? ?// 創(chuàng)建關(guān)閉按鈕組件
? ? ? ?this.closeBtn = document.createElement('b');
? ? ? ?// 為提示框面板添加類
? ? ? ?this.panel.className = 'alert';
? ? ? ?// 為確定按鈕組件添加類
? ? ? ?this.confirmBtn.className = 'a-confirm';
? ? ? ?// 為取消按鈕組件添加類
? ? ? ?this.closeBtn.className = 'a-close';
? ? ? ?this.closeBtn.innerHTML = 'X';
? ? ? ?// 為確定按鈕添加文案
? ? ? ?this.confirmBtn.innerHTML = data.confirm || '確定';
? ? ? ?// 為提示內(nèi)容添加文本
? ? ? ?this.contentNode.innerHTML = this.content;
? ? ? ?// 點(diǎn)擊確定按鈕執(zhí)行方法,如果 data 中有 success 方法則為 success 方法,否則為空函數(shù)
? ? ? ?this.success = data.success || function () {}
? ? ? ?// 點(diǎn)擊關(guān)閉按鈕執(zhí)行方法
? ? ? ?this.fail = data.fail || function () {}
? ?}
init() {
? ? ? ?this.panel.appendChild(this.closeBtn);
? ? ? ?this.panel.appendChild(this.contentNode);
? ? ? ?this.panel.appendChild(this.confirmBtn);
? ? ? ?// 插入頁面中
? ? ? ?document.body.appendChild(this.panel);
? ? ? ?// 綁定事件
? ? ? ?this.bindEvent();
? ? ? ?// 顯示提示框
? ? ? ?this.show();
? ?}
bindEvent() {
? ? ? ?var me = this;
? ? ? ?this.closeBtn.onclick = function () {
? ? ? ? ? ?// 執(zhí)行關(guān)閉方法
? ? ? ? ? ?me.fail();
? ? ? ? ? ?// 隱藏彈層
? ? ? ? ? ?me.hide();
? ? ? ?}
? ? ? ?this.confirmBtn.onclick = function () {
? ? ? ? ? ?// 執(zhí)行確定方法
? ? ? ? ? ?me.success();
? ? ? ? ? ?// 隱藏彈層
? ? ? ? ? ?me.hide();
? ? ? ?}
? ?}
? ?// 隱藏彈框的方法
hide() {
? ? ? ?this.panel.style.display = 'none';
? ?}
? ?// 展示彈框的方法
show() {
? ? ? ?this.panel.style.display = 'block';;
? ?}
}
document.getElementById('showNormalBtn').addEventListener('click', function() {
? ?new Alert({
? ? ? ?content: '普通內(nèi)容'
? ?}).init()
})

16.6、繼承類也可以作為模版類
class AlertConfirmCancel extends Alert {
constructor(data) {
? ? ? ?super(data);
? ? ? ?// 創(chuàng)建取消按鈕組件
? ? ? ?this.cancelBtn = document.createElement('div');
? ? ? ?this.cancelBtn.className = 'a-btn a-cancel';
? ? ? ?// 為確定按鈕添加文案
? ? ? ?this.cancelBtn.innerHTML = data.confirm || '取消';
? ? ? ?this.cancelFn = data.cancelFn || function () {}
? ?}
init() {
? ? ? ?super.init()
? ? ? ?this.panel.appendChild(this.cancelBtn);
? ?}
bindEvent() {
? ? ? ?super.bindEvent()
? ? ? ?const me = this
? ? ? ?this.cancelBtn.onclick = function () {
? ? ? ? ? ?// 執(zhí)行徐曉方法
? ? ? ? ? ?me.cancelFn();
? ? ? ? ? ?// 隱藏彈層
? ? ? ? ? ?me.hide();
? ? ? ?}
? ?}
}
document.getElementById('showConfirmCancelBtn').addEventListener('click', function() {
? ?new AlertConfirmCancel({
? ? ? ?content: '又有取消又有確定'
? ?}).init()
})

模版方法的核心在于對方法的重用,它將核心方法封裝在基類中,讓子類繼承基類的方法實(shí)現(xiàn)基類的共享。
我們一般在基類中封裝不變的算法或者具有穩(wěn)定的調(diào)用方式。
子類繼承基類的時候,可以重寫繼承的方法,同時也可以復(fù)用繼承的方法。
本章 End
加油加油
2021年02月23日 D1n910 學(xué)習(xí)于南山后海