軟體設計模式 | 模板模式 : 以Vue.js為例

更新於 發佈於 閱讀時間約 8 分鐘
模板模式的定義極為簡單,卻是大型系統程式、WEB/APP應用框架的設計核心,完美展現設計模式的價值: 簡單、高效、強大。
raw-image

定義

由父類別制定演算法的執行步驟, 將每個步驟的實作細節延後由子類別實現。

模板模式的定義雖然簡單,但對於初學者來說,往往難以真正體會其背後的概念與優勢。然而,透過經典的應用場景範例,這些概念與優勢就變得清晰易懂。


WEB前端框架生命週期 : VUE.js

在Vue.js編譯完成後,會生成一個包含 "app" id 的 index.html 作為首頁。當開啟網頁時,瀏覽器會將編譯後的整包 JavaScript 掛載到這個 "app" DOM元素上,並建立 Vue應用實例,負責監控網頁與使用者的所有互動以及從網路端獲取的資訊。

應用頁面的生命週期回調函數

當我們導航到客製化開發的應用頁面時,Vue應用實例會將該頁面實例化為Vue組件(component),並依次呼叫該組件的生命週期回調函數。

我們則需要在合適的回調函數內實作業務邏輯。以下是各個生命週期回調函數的實際應用範例:

onBeforeMount

在組件即將被掛載到 DOM 之前呼叫。通常會在這個階段呼叫透端API準備資料。

onBeforeMount(() => {
// 通常在這裡call API準備要顯示的資料
try {
this.data = (await axios.get('/api/data')).data;
} catch (error) {
this.error = error; console.error('Error fetching data:', error); }
});

onMounted

在組件掛載到DOM之後呼叫,這是開發著可以開始訪問和操作DOM元素的地方。適合在這裡進行與DOM相關的初始化操作,例如初始化圖表或設置事件監聽器。

最重要的是,如果在template裡有設定ref,onMounted後就可以開始操作他了。

<template>
<div ref="chartContainer">
這是我的圖表容器
</div>
</template>

<script>
import { onMounted, ref } from 'vue';

export default {
setup() {
const chartContainer = ref(null);

onMounted(() => {
// 操作ref
chartContainer.value.init();

// 有時候想要監聽視窗大小的改變進行畫面上的處理
window.addEventListener('resize', handleResize);
});
},
};
</script>

onBeforeUpdate

在數據更新之前呼叫,此時虛擬DOM(Virtual DOM)已經重新渲染,但新的數據還未應用到真實DOM中。這裡可以進行一些在數據改變後需要在DOM更新前完成的操作。

onBeforeUpdate(() => {
// 可以在這裡進行一些準備工作
console.log("onBeforeUpdate: 數據即將更新");
});

onUpdated

在數據更新並且虛擬DOM重新渲染和差異更新完成之後調用,這時可以進行與更新後DOM相關的操作。

onUpdated(() => { 
// 可以在這裡執行與更新後 DOM 相關的操作
console.log('onUpdated: 數據更新完成,DOM 已重新渲染');
});

onBeforeUnmount

Vue組件被卸載之前調用,通常用於進行一些清理工作,例如移除事件監聽器。

onBeforeUnmount(() => { 
// 移除事件監聽器 window.removeEventListener('resize', handleResize);
console.log('onBeforeUnmount: 組件即將被卸載');
});

onUnmounted

Vue組件被完全卸載並且不再存在於DOM中時調用,可以在這裡進行最終的清理操作,例如銷毀圖表實例。

onUnmounted(() => { 
console.log('onUnmounted: 組件已經從 DOM 中移除');
// 銷毀圖表實例
destroyChart();
});

其他框架的模板設計

Android APP(手機應用框架): Activity生命週期回調函數

onCreate:應用程式第一次開啟時呼叫。例如設定佈局、初始化資料等。

onStart:應用程式即將可見時呼叫。進行界面更新等操作。

onResume:應用程式與使用者互動前的最後準備。例如恢復播放動畫。

onPause:系統即將啟動另一個活動時呼叫。例如暫停播放動畫或音樂。

onStop:應用程式不再可見時呼叫。例如停止播放動畫或音樂、保存應用程式狀態。

onDestroy:應用程式即將被銷毀時呼叫。執行最終清理工作,釋放所有資源。

onRestart:應用程式從停止狀態重新啟動時呼叫。恢復暫停前的操作。

由於手機與使用者的互動即時性比網頁更高,並且涉及了更多系統層級的資源管理,因此Android APP的生命週期更加複雜。開發者需要在合適的回調函數中,更細膩地關注使用者與系統的行為,並處理業務邏輯。


Pytest(Python測試框架) : Test Class回調函數Test Method回調函數

  • setup_class:在整個測試類別開始前呼叫。
  • teardown_class:在整個測試類別結束後呼叫。
  • setup_method:在每個測試案例開始前呼叫。
  • teardown_method:在每個測試案例結束後呼叫。

在撰寫測試腳本時,有一些初始化狀態的前置作業是整個類別共用的,需要在整個類別測試開始時執行一次,並在整個類別測試結束後清理。有些則是每個測試案例開始前執行,測試案例結束後清理。為了方便開發人員在不同的時機撰寫相關的測試邏輯,Pytest 提供了四種回調函數,幫助開發人員根據需求選擇合適的使用時機。


關鍵影響

從實際的應用可以看出,應用框架的設計者使用模板模式預先定義好網頁應用程式、手機應用程式、測試腳本的執行步驟。

使用者可以在這些既定步驟下實作業務需求,但這些步驟的呼叫時機卻是由系統決定。這樣的設計具有以下這些優勢。

一致性:確保整個系統的算法結構和流程一致,避免因個別實現差異而導致的不可預測行為。

靈活性:父類別定義通用流程,子類別可以根據具體需求覆寫部分步驟,使得同一流程可以適應不同的情境和需求。

重用性:父類別中的通用部分可以被多個子類別重用,減少程式碼重複,提高程式碼的可維護性和擴展性。

控制權限:父類別控制流程的執行順序,確保關鍵步驟不會被子類別隨意修改,保障系統的穩定性和安全性。

清晰分工:將算法的固定部分與可變部分分離,使得程式碼結構更加清晰,便於理解和維護。


隱藏的缺點 : 呼叫控制的反轉

雖然模板模式有諸多好處,但這種體現好萊塢原則("Don't call us, we'll call you")的設計反轉了函數的呼叫控制。

這樣的設計卻可能會導致我們開發出許多自己都不知道為什麼能正常運行的程式。

原因在於一些簡單的業務邏輯在各個不同的回調函數下實作時可能不會發生問題,這反而會讓工程師誤以為自己已經完全理解了框架的運作原理。

直到BUG實際在客戶手上發生的那一天,工程師們才能真正感受到誤用框架的恐懼。

當你在凝視框架的同時,框架也在凝視著你。

圖片來源: google

圖片來源: google

avatar-img
66會員
19內容數
探索自我實現的小角落。沒有高高在上的教條,只有真實的分享和心得。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
再寫5分鐘 的其他內容
你知道IG是用Django開發的嗎? 正在學習或使用Django、Flask框架開發後端的你,是否也常在享受Python語法的舒適之餘,仍然煩惱著是否該學習效率更好的GO或Laravel。
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
策略模式將多種演算法封裝於獨立的策略類別中,每個策略類別都實現了一個共同的介面。這種設計允許使用者在系統運行時動態選擇和切換演算法,以達成相同的目的。
你知道IG是用Django開發的嗎? 正在學習或使用Django、Flask框架開發後端的你,是否也常在享受Python語法的舒適之餘,仍然煩惱著是否該學習效率更好的GO或Laravel。
觀察者模式透過主題訂閱/訊息通知的機制,極度增強系統的可擴展性、靈活性以及降低組件間的耦合度。概念直觀簡單,是非常實用的設計模式。
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
代理模式通過封裝原始對象來實現對該對象的控制和管理,同時不改變原始對象的行為或客戶端與該對象互動的方式,以此介入或增強對該對象的訪問和操作。
策略模式將多種演算法封裝於獨立的策略類別中,每個策略類別都實現了一個共同的介面。這種設計允許使用者在系統運行時動態選擇和切換演算法,以達成相同的目的。
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
列出一套完整的程式 程式設計有許多種方法,不過通常會先列出清單的再逐一執行,這樣會加快程式設計的速度。設計通常會採取順推的辦法。所以順推的程式設計方式就是經歷觀念溝通、系統分析、資料統合、權限管理、頻率與時間、後台管理、畫面設計等等階段後,將框架設計完了以後,先列出一套完整的程式,將所有使用者都確
Thumbnail
程式設計中不可或缺的一部分 介面是使用者與程式互動的媒介,因此介面的設計會影響使用者的體驗和感受。一個清晰明白、易懂的介面,可以讓使用者輕鬆地使用程式,並獲得良好的使用體驗。 需要與程式設計師密切溝通 設計師需要了解程式的功能和需求,並根據使用者的習慣和需求進行設計。設計師和程式設計師之間的溝
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
自訂元件生成位置顧名思義就是可以指定部分HTML區塊渲染在特定的畫面上,即使在不同組件也能把A組件內的部分畫面,展現在B組件上,以下方程式舉例。
Thumbnail
Vue.js是一種基於MVVM的前端JavaScript框架,類似的框架有React、Angular等。 架設環境 安裝Visual Studio Code(https://code.visualstudio.com/) 安裝Node.js(https://nodejs.org/en/
Thumbnail
Vue Router 及 具名視圖,擺脫以往切換依賴 CSS display:none 跟 display:block 互相配合,有時還得搭配 z-index 來調整層級跟 opacity 透明度的麻煩,而 Vue Router 完美的解決了這棘手的問題,且能客製頁面想要呈現的擺飾。
Thumbnail
列出一套完整的程式 程式設計有許多種方法,不過通常會先列出清單的再逐一執行,這樣會加快程式設計的速度。設計通常會採取順推的辦法。所以順推的程式設計方式就是經歷觀念溝通、系統分析、資料統合、權限管理、頻率與時間、後台管理、畫面設計等等階段後,將框架設計完了以後,先列出一套完整的程式,將所有使用者都確
Thumbnail
程式設計中不可或缺的一部分 介面是使用者與程式互動的媒介,因此介面的設計會影響使用者的體驗和感受。一個清晰明白、易懂的介面,可以讓使用者輕鬆地使用程式,並獲得良好的使用體驗。 需要與程式設計師密切溝通 設計師需要了解程式的功能和需求,並根據使用者的習慣和需求進行設計。設計師和程式設計師之間的溝