動態改變畫面時的資料處理策略

更新於 2024/12/18閱讀時間約 5 分鐘


raw-image

開發客戶端程式時,有些時候後端傳過來的資料根據情況變化,畫面也有所不同。舉例來說,當使用者登入系統時,後端會根據使用者的權限等級傳送不同的資料,使畫面呈現出不同的功能和選項。另一個例子是,在我們的開發的遊戲中,顯示比賽列表的畫面,也會根據不同的場次型態,顯示不同的卡片樣式。

當回傳資料不一致時,會發生許多 if 判斷式散佈在各個地方,這就是所謂的 Shortgun Surgery 問題。換句話說,當你需要修改一個功能時,你需要在多個地方進行修改,這樣會導致代碼的耦合性增加,並且增加了代碼的維護成本。

舉個例子

在我們的遊戲中,後端會給前端每一場比賽資料,讓前端可以顯示比賽資訊。在下圖中,我們從後端接收了一個 Json 物件,然後把 Json 物件轉換成 Contest 物件,最後一路傳到 View,給 View 決定如何顯示畫面。

raw-image

在上面的例子中,不同的 Contest 型態,有不同的卡片樣式,當 Contest 的類型不同,後端可能也會根據不同的 Contest 而給前端不同資料,假設我們使用的強型別的語言,那我們到底要如何把不同的 Json 轉成同一個物件呢?

萬能的 Value Object

最簡單解決問題的方式,我們可以在 Contest 放上所有可能的出現的資料,View 則是根據自己的需要選擇相對應的欄位使用。以 Practice Contest View 來說,他只會使用 type 與 spots,但對 Non-Pratice Contest 來說,則是所有欄位都會使用。

raw-image

優點

  • 容易使用

缺點

  • 使用端依賴了他不需要的東西,違反介面隔離的原則,以 Practice Contest 來說,他並不需要 entryFee 與 maxPrizePool

轉接器模式

另一個例子是,在下面的畫面中,可以發現大部分的畫面樣式都相同,唯一不同的是球員的資訊,不同球類的球員,顯示不同的數值來展示球員的過去表現。以板球球員來說,我們使用 Batting 與 Bowling 表示球員綜合表現,以足球來說,則是使用 Points 表示。

raw-image

raw-image

此時大部分的資料都是類似的,只有少部分關於球員表現的資料略微不同,我們可以使用轉接器模式,把後端傳回來的資料,轉換成另一種格式,讓畫面可以用一致的方式操作資料。

raw-image

以球員表現的例子來説,我們可以把新增一個 Map,用以儲存每種球員數據的 Enum 與其數字,View 在使用時,就可以顯示 Map 中的所有數據即可,而無須關心到底是板球還是足球。

優點

  • 畫面可以使用一致的邏輯處理資料

缺點

  • 當資料差異畫過大時,難以整理成一種共用的格式

策略模式

在我們的遊戲中,我們有許多不同的廣告,有時是單純的一張圖,有時是比賽資訊,而後端則是根據不同情況傳回不同資料。與球員數據問題類似,我們都接收來自後端不大相同的資料,但不同的是,這些資料幾乎沒有共通性,我們難以使用轉接器模式整理出一致的格式。

raw-image

raw-image

為了解決這個問題,我們可以使用策略模式,提供一個包含 buildComponent 的方法的介面。當 AdView 從 Controller 取得 Ad 物件時,呼叫 Ad 物件身上的 buildComponent 方法取得顯示用的 Component。 當我們這樣做之後,View 再也無需關心現在到底是哪一種廣告,只需要呼叫 buildComponent 即可取得相對應的廣告畫面,並把它塞進畫面中即可。

raw-image

在 GeneralAd 與 ContestAd 中,它們會各自實現 buildComponent,提供該類型廣告的 Widget 給 View 顯示。

優點

  • 畫面可以使用一致的邏輯處理資料

缺點

  • Value Object 會認識 View

結論

由於客戶端畫面可能會相當多變,後端可能會給一個 type,不同 type 所包含的資料格式也大不相同,如何處理這個資料與畫面的關係也沒有標準答案,即便問題相似,但是在不同的 Context 之下,也適合不同的解法,只有根據當下情況選擇適當的做法,才能讓後續開發與維護更加順利。

分享各種軟體開發技巧與心得
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
本文介紹如何利用 Flutter 框架和 Flame 遊戲引擎製作一個簡單的點擊小遊戲。從導入 Flame 套件,到使用 GameWidget,接著為遊戲中的騎士角色添加動作,最後實現點擊計數功能,這篇文章一步步帶你體驗遊戲開發的樂趣,讓你掌握基本的遊戲設計和邏輯編程技巧。
本文分享瞭如何使用 Notion Web Clipper 來儲存文章,並結合 Habit Stacking 技術克服維持新習慣的困難。同時探討如何使用 Flutter Web 和 Notion API 開發自用的 Chrome 擴展功能,提升個人資訊管理和閱讀效率。
Flutter Widget 能加速開發,但誤用 MediaQuery 可能導致不預期的重建。範例中,頁面因鍵盤觸發高度變動而刷新,隨機數重新生成。使用固定比例設計避免重建,顯示深入理解框架對穩定性的重要性。
Flutter 習慣在最頂層的 MaterialApp 或 CupertinoApp 中統一定義整個 app 的路由管理。當我們把所有頁面的路由管理都放在最頂層時,就會讓它變得很長,不容易維護。或許應該適時思考,是否某些頁面的路由不應該被管理在最頂層。
這篇文章說明在 Flutter App 中整合 Google Play 內購功能的流程。主要包含兩個部分:先在 Google Play Console 設定商品,然後使用 Flutter 的 in_app_purchase 套件實作購買功能。開發時需注意連線狀態、商品列表獲取,以及購買流程的實作。
本文介紹如何利用 Flutter 框架和 Flame 遊戲引擎製作一個簡單的點擊小遊戲。從導入 Flame 套件,到使用 GameWidget,接著為遊戲中的騎士角色添加動作,最後實現點擊計數功能,這篇文章一步步帶你體驗遊戲開發的樂趣,讓你掌握基本的遊戲設計和邏輯編程技巧。
本文分享瞭如何使用 Notion Web Clipper 來儲存文章,並結合 Habit Stacking 技術克服維持新習慣的困難。同時探討如何使用 Flutter Web 和 Notion API 開發自用的 Chrome 擴展功能,提升個人資訊管理和閱讀效率。
Flutter Widget 能加速開發,但誤用 MediaQuery 可能導致不預期的重建。範例中,頁面因鍵盤觸發高度變動而刷新,隨機數重新生成。使用固定比例設計避免重建,顯示深入理解框架對穩定性的重要性。
Flutter 習慣在最頂層的 MaterialApp 或 CupertinoApp 中統一定義整個 app 的路由管理。當我們把所有頁面的路由管理都放在最頂層時,就會讓它變得很長,不容易維護。或許應該適時思考,是否某些頁面的路由不應該被管理在最頂層。
這篇文章說明在 Flutter App 中整合 Google Play 內購功能的流程。主要包含兩個部分:先在 Google Play Console 設定商品,然後使用 Flutter 的 in_app_purchase 套件實作購買功能。開發時需注意連線狀態、商品列表獲取,以及購買流程的實作。
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
在開發應用程式時,經常會遇到需要調整圖片大小以節省空間或加快加載速度的情況。本教學將介紹如何使用 C# 語言來壓縮圖片並調整其大小,以便在應用程式中使用。
Thumbnail
題目敘述 題目會給我們一組定義好的界面和需求,要求我們設計一個資料結構,可以滿足平均O(1)的插入元素、刪除元素、隨機取得元素的操作。 RandomizedSet() 類別建構子 bool insert(int val) 插入元素的function界面 bool remove(int val
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
在開發應用程式時,經常會遇到需要調整圖片大小以節省空間或加快加載速度的情況。本教學將介紹如何使用 C# 語言來壓縮圖片並調整其大小,以便在應用程式中使用。
Thumbnail
題目敘述 題目會給我們一組定義好的界面和需求,要求我們設計一個資料結構,可以滿足平均O(1)的插入元素、刪除元素、隨機取得元素的操作。 RandomizedSet() 類別建構子 bool insert(int val) 插入元素的function界面 bool remove(int val