摘要
當工程師面對20個品牌的白標App需求時,那種在共用邏輯與品牌差異間反覆橫跳的崩潰感——這篇就是我們的生存手札,帶你看清技術決策背後的人性掙扎。 歸納要點:
- 白標系統的共用與差異化平衡術:從主題token到元件覆蓋,那些我們踩過的坑大概可以繞辦公室三圈——特別是當A牌突然要求獨家onboarding流程時
- monorepo實戰心得:用TypeScript參照結構和Yarn Workspace打架的日子,意外發現部署自動化工具才是真愛(雖然同事至今還在爭論哪部分最關鍵)
- 「一份底層N種面貌」的幻滅與重生:按鈕共享破局時,才懂所謂靈活架構根本是邊改邊哭出來的產物
有時候,開發一套可以給不同品牌用的行動應用程式,看起來好像只是把某個商標換掉、主色調改一改。可是,其實要讓這種「白標系統」真的能長期維護又能隨需求擴張,事情遠比想像複雜。
像我之前待過的那間SaaS公司,主要做寵物服務產業的平台。後來陸續有一些規模比較大的客戶來詢問,他們不太滿足於單純共享預約功能這種模式。他們想要專屬自己的app,不只是表面變一變,而是希望從外觀到操作都要貼近自家品牌氛圍,甚至連一些流程也要能客製化,更別提和終端用戶的聯繫權限。
我們那時選了React Native當基礎。其實一開始沒想到會遇到那麼多狀況,只覺得跨平台方便。不過說真的,用舊有那種大而全的應用架構,在應付各式品牌需求時,很快就會卡住。不僅是介面主題換顏色而已,有些地方必須徹底重想結構設計、佈署方式甚至開發人員怎麼協作,都得調整才行。有些細節如果沒處理好,不只效能可能受到影響,程式碼也容易混亂,到頭來上線速度反而拖慢不少。
回頭看,好像沒有哪一步是完全照著原本預期走的——畢竟每個品牌說不定都還藏著自己的一點堅持或小訣竅。
像我之前待過的那間SaaS公司,主要做寵物服務產業的平台。後來陸續有一些規模比較大的客戶來詢問,他們不太滿足於單純共享預約功能這種模式。他們想要專屬自己的app,不只是表面變一變,而是希望從外觀到操作都要貼近自家品牌氛圍,甚至連一些流程也要能客製化,更別提和終端用戶的聯繫權限。
我們那時選了React Native當基礎。其實一開始沒想到會遇到那麼多狀況,只覺得跨平台方便。不過說真的,用舊有那種大而全的應用架構,在應付各式品牌需求時,很快就會卡住。不僅是介面主題換顏色而已,有些地方必須徹底重想結構設計、佈署方式甚至開發人員怎麼協作,都得調整才行。有些細節如果沒處理好,不只效能可能受到影響,程式碼也容易混亂,到頭來上線速度反而拖慢不少。
回頭看,好像沒有哪一步是完全照著原本預期走的——畢竟每個品牌說不定都還藏著自己的一點堅持或小訣竅。
設計白標行動應用系統這種事情,現場狀況有時候挺複雜的。光是怎麼保留一套共用程式邏輯、又能讓不同品牌之間各自有差異,這就夠人頭大了。回想當初,我們試圖分清楚什麼東西該保持一致、哪些地方可以讓它們長得不一樣——每個品牌的外觀、功能甚至執行時的細節,有些要統一,有些好像又非得拆開來弄。
其實核心的大原則也沒多罕見,就是那種「一份底層程式,外表和行為卻能搞出七八種」那路數。只是落地的時候,總覺得比想像中還容易繞進死胡同。有時候設計完才發現某個按鈕或流程根本不能共享,或是哪家品牌突然冒出獨有的 onboarding 流程,要臨時改架構。
說到技術面,大致分成幾塊:最下面那層是顏色字體間距等主題 token,上面鋪的是通用元件(像什麼彈窗按鈕那些),但常常又要被不同品牌各自覆蓋掉。比如 A 牌堅持加自己的 onboarding,新功能老早就不是一次搞定全部,只能拆著做。有些人會畫個圖示意,不過通常都是幾條線連來連去,中間還夾雜一些模糊記憶。
對了,後來團隊把整包東西塞進 monorepo(其實類似「好幾套子專案疊在一起」那種組織形式),然後用 TypeScript 那套參照結構來區隔,不同模組彼此之間有基本驗證,方便抓 bug,也比較不會哪天莫名其妙撞壞別人的功能。 Yarn Workspace 在這裡也派上點用場。不過到底哪部分最關鍵,其實大家感受不太一樣,也有人認為部署自動化和內部小工具更省力,只是這又是另外一段故事了。
其實核心的大原則也沒多罕見,就是那種「一份底層程式,外表和行為卻能搞出七八種」那路數。只是落地的時候,總覺得比想像中還容易繞進死胡同。有時候設計完才發現某個按鈕或流程根本不能共享,或是哪家品牌突然冒出獨有的 onboarding 流程,要臨時改架構。
說到技術面,大致分成幾塊:最下面那層是顏色字體間距等主題 token,上面鋪的是通用元件(像什麼彈窗按鈕那些),但常常又要被不同品牌各自覆蓋掉。比如 A 牌堅持加自己的 onboarding,新功能老早就不是一次搞定全部,只能拆著做。有些人會畫個圖示意,不過通常都是幾條線連來連去,中間還夾雜一些模糊記憶。
對了,後來團隊把整包東西塞進 monorepo(其實類似「好幾套子專案疊在一起」那種組織形式),然後用 TypeScript 那套參照結構來區隔,不同模組彼此之間有基本驗證,方便抓 bug,也比較不會哪天莫名其妙撞壞別人的功能。 Yarn Workspace 在這裡也派上點用場。不過到底哪部分最關鍵,其實大家感受不太一樣,也有人認為部署自動化和內部小工具更省力,只是這又是另外一段故事了。
觀點延伸比較:
主題 | 關鍵要點 | 結論 |
---|---|---|
分離設計與邏輯 | 隨著多品牌支持的需求增加,設計和邏輯逐漸分離,讓客製化更靈活。 | 這樣的策略可以減少代碼複雜度並提升維護性。 |
功能旗標策略 | 使用結構化的功能旗標來管理不同品牌需求,避免亂用 if-else 判斷。 | 集中管理功能旗標有助於追蹤紀錄和分析數據。 |
自動化部署流程 | 導入 CI/CD 以應對多品牌和版本更新的挑戰,自動檢查能夠提前攔下潛在錯誤。 | 自動化提升了工作效率,減少了人為疏失的可能性。 |
預覽包版本發布 | 提供專屬預覽包給合作方,以便提前查看成果,增強溝通效果。 | 這種方式使非工程師也能輕鬆掌握進度,降低修改需求的麻煩。 |
模組化與彈性思維 | 將客製化內容分開處理,提高系統擴展性及後續維護便利性。 | 清晰的責任劃分與模組化設計是長期經營成功的重要基石。 |

他們的專案結構其實有點像分層蛋糕,最下面那層叫 core,有一些大家都得用到的商業邏輯、UI 元件、還有工具類的東西。再往上一些就是 brand-configs,這部分好像專門放每個品牌自己的顏色、資產檔、風格覆寫之類(偶爾會混進點元數據)。apps 那邊,每個品牌都有自己獨立的小 app 入口,看起來只是薄薄一層外殼,用來打包 Android/iOS 的版本。至於 tooling,基本上就是一些命令列小工具、驗證腳本或自動產生代碼的小幫手。
這樣子的分法,讓依賴關係很明顯:比如 apps/brandA 需要 core 裡頭的共用東西,可是 core 絕對不會反過來去碰品牌相關內容。至於開發流程,不知道是不是因為用了增量編譯加熱重載,所以在本地切換不同品牌時速度蠻快的。有些工程師說測試規模也變靈活了,每一層都能各自跑單元或整合測試,不太容易互相干擾。
稍微跳開一點,其實每次啟動時,各家 app 都會讀進一份結構化設定檔,用它調整視覺跟行為。有聽說那些設定主要涵蓋顏色字體間距啊,然後功能開關(像某些新流程要不要先藏起來),頁面導航長怎樣(標籤式還是疊加堆疊),甚至連區域策略或會員權限,也都能在設定裡控制。例如,他們可能寫成:
const brandConfig = {
theme: { primaryColor: '#0088CC', font: 'Inter' },
features: { enableLiveUpdates: true, enableRewardsFeature: false },
navigation: { useTabLayout: true },
policies: { requiresEmailVerification: false }
}
這種方式下,同一套主程式就可以跑出好幾款外觀截然不同的產品——基本沒什麼重複程式碼,只要換資料就行。當然怕出錯,他們還特別用 zod 去定義 schema,而且靜態分析也會協助抓用法問題;大概多多少少降低了一點維護風險吧。
講回 app 的進入點,每個品牌自己都有個 index.ts 之類的東西——先從 core 裡叫出 createApp,再丟進該品牌專屬 config。有時候遇到特殊需求,好像也能掛上客製化組件或者業務邏輯,就像是在主架構旁邊接插件那樣。
這種模式給他們帶來幾個還算實用的優勢,比如每個品牌最後都能輸出自己獨立包(icon、bundle id、環境參數全都是各管各的),所以發佈更新不用卡在一起。再說萬一哪家有自己的奇怪需求,也可以直接針對那家做覆寫,而不必修改共用底層。
總體來看,他們把「品牌」視為可以組合變化的資料設定,把「平台核心」設計成模組拼裝模式,因此沒什麼分支或衍生副本需要同時維護,比較不容易搞混也比較好追蹤改動。至於最後有沒有真的省下多少工夫,大概還得看團隊習慣和具體應用場景,但至少短時間內,他們已經靠這套方法推出了將近二十款左右長得完全不一樣但底子一致的新 app。
這樣子的分法,讓依賴關係很明顯:比如 apps/brandA 需要 core 裡頭的共用東西,可是 core 絕對不會反過來去碰品牌相關內容。至於開發流程,不知道是不是因為用了增量編譯加熱重載,所以在本地切換不同品牌時速度蠻快的。有些工程師說測試規模也變靈活了,每一層都能各自跑單元或整合測試,不太容易互相干擾。
稍微跳開一點,其實每次啟動時,各家 app 都會讀進一份結構化設定檔,用它調整視覺跟行為。有聽說那些設定主要涵蓋顏色字體間距啊,然後功能開關(像某些新流程要不要先藏起來),頁面導航長怎樣(標籤式還是疊加堆疊),甚至連區域策略或會員權限,也都能在設定裡控制。例如,他們可能寫成:
const brandConfig = {
theme: { primaryColor: '#0088CC', font: 'Inter' },
features: { enableLiveUpdates: true, enableRewardsFeature: false },
navigation: { useTabLayout: true },
policies: { requiresEmailVerification: false }
}
這種方式下,同一套主程式就可以跑出好幾款外觀截然不同的產品——基本沒什麼重複程式碼,只要換資料就行。當然怕出錯,他們還特別用 zod 去定義 schema,而且靜態分析也會協助抓用法問題;大概多多少少降低了一點維護風險吧。
講回 app 的進入點,每個品牌自己都有個 index.ts 之類的東西——先從 core 裡叫出 createApp,再丟進該品牌專屬 config。有時候遇到特殊需求,好像也能掛上客製化組件或者業務邏輯,就像是在主架構旁邊接插件那樣。
這種模式給他們帶來幾個還算實用的優勢,比如每個品牌最後都能輸出自己獨立包(icon、bundle id、環境參數全都是各管各的),所以發佈更新不用卡在一起。再說萬一哪家有自己的奇怪需求,也可以直接針對那家做覆寫,而不必修改共用底層。
總體來看,他們把「品牌」視為可以組合變化的資料設定,把「平台核心」設計成模組拼裝模式,因此沒什麼分支或衍生副本需要同時維護,比較不容易搞混也比較好追蹤改動。至於最後有沒有真的省下多少工夫,大概還得看團隊習慣和具體應用場景,但至少短時間內,他們已經靠這套方法推出了將近二十款左右長得完全不一樣但底子一致的新 app。
多品牌主題系統這種東西,其實不太只是換個顏色或標誌那麼單純。據說,為了讓每一個畫面都能貼合各自品牌的氛圍,同時又不會搞得共用元件庫過於雜亂,很多團隊最後都是想辦法組出一層比較有彈性的主題結構。也有人會說設計語言要原子化,那就得靠所謂「設計代幣」來處理——比方說,像顏色、間距、字型、圓角這些細節,每個品牌大概都準備了一份自己的設定檔,有的項目甚至還是臨時才塞進去的。
舉個例子,大致長這樣:
const themeBrandA = {
primaryColor: '#FF7F50',
headingFont: 'Garamond',
borderRadius: 8,
spacingUnit: 4,
}
反正重點就是在那些共用的元件裡面,不容許直接寫死任何跟外觀有關的數值,連臨時測試都不給過。有些人乾脆弄個主題提供器,再加上一套叫 useTheme() 的自定義 hook;還有人訂了點挺嚴格的 lint 規則,只要誰偷偷加了什麼內聯樣式(像字體大小啊、顏色之類),基本上立刻就被抓出來。有時候他們好像還拿快照比對方式,看哪些地方無意間讓不同品牌跑出預期外的新樣式,好像滿常見。
至於萬一某個品牌漏掉某些設定呢?通常也不是什麼大事啦,因為大家都習慣先備一份預設代幣,有缺值就回退到那邊,也算能稍微兜起來。不過實作上偶爾難免有些地方沒那麼完美,但整體看起來,在多數情境下還算能撐住。
舉個例子,大致長這樣:
const themeBrandA = {
primaryColor: '#FF7F50',
headingFont: 'Garamond',
borderRadius: 8,
spacingUnit: 4,
}
反正重點就是在那些共用的元件裡面,不容許直接寫死任何跟外觀有關的數值,連臨時測試都不給過。有些人乾脆弄個主題提供器,再加上一套叫 useTheme() 的自定義 hook;還有人訂了點挺嚴格的 lint 規則,只要誰偷偷加了什麼內聯樣式(像字體大小啊、顏色之類),基本上立刻就被抓出來。有時候他們好像還拿快照比對方式,看哪些地方無意間讓不同品牌跑出預期外的新樣式,好像滿常見。
至於萬一某個品牌漏掉某些設定呢?通常也不是什麼大事啦,因為大家都習慣先備一份預設代幣,有缺值就回退到那邊,也算能稍微兜起來。不過實作上偶爾難免有些地方沒那麼完美,但整體看起來,在多數情境下還算能撐住。

有些品牌追求的東西,好像遠不只調個顏色或換下字型那麼簡單。偶爾會遇到幾家合作夥伴,他們想把自家的 onboarding 流程整個改頭換面,還有人非要塞進專屬的說明小工具。這種情況下,要是直接在應用裡面加分支判斷,沒多久就可能被搞得一團亂。那時候,大約想了個外掛式覆寫的做法──其實跟某些人講的「插件」倒也差不多,但我們更傾向把這類 override 當成一種契約,而不是例外處理。
他們設了一份像登記冊那樣的註冊表,把各品牌想要替換的畫面元件或行為,一項一項列清楚。例如 onboarding 走自己的流程,支援 widget 沒特別需求就用預設。到實際運作時,只需要查查這張表,有特製版本就切過去,沒有就回歸主流寫法。好處嘛,大致上是每個品牌自己該改哪邊都很明確,不容易牽連一大片,也方便後續檢查到底誰覆蓋了什麼地方,甚至哪天不想用了,把對應欄位清掉就能還原。
順帶一提,那陣子工程團隊跟設計、PM 常常來回溝通,光靠書面文件反覆確認效果也挺累人的。有次閒聊中,有人提議乾脆做個現場預覽沙盒(剛好 Storybook 這類工具當時已經蠻流行),結果滿多人都覺得有點道理。不久之後,就出現了能即時切換品牌視覺、模擬特殊狀況(像文字暴長或暗色模式)、甚至連 QA 都拿來驗證樣式變動的小工具。還記得測試階段,有將近三分之一的新問題,其實就是靠這種預覽才提前抓到。不僅工程師覺得省事,連非技術背景的人也樂於參與討論,看起來對縮短溝通周期確實有幫助。
說到底,「主題化」並不是單純換皮膚那麼輕鬆;這背後更多是在架構層面的思考。如果只當它是 CSS 小事,很容易忽略那些深層系統性的需求。不過,每家公司做法都不盡相同,上述經驗頂多算是一種嘗試吧,有些細節恐怕也未必適合所有場景。
他們設了一份像登記冊那樣的註冊表,把各品牌想要替換的畫面元件或行為,一項一項列清楚。例如 onboarding 走自己的流程,支援 widget 沒特別需求就用預設。到實際運作時,只需要查查這張表,有特製版本就切過去,沒有就回歸主流寫法。好處嘛,大致上是每個品牌自己該改哪邊都很明確,不容易牽連一大片,也方便後續檢查到底誰覆蓋了什麼地方,甚至哪天不想用了,把對應欄位清掉就能還原。
順帶一提,那陣子工程團隊跟設計、PM 常常來回溝通,光靠書面文件反覆確認效果也挺累人的。有次閒聊中,有人提議乾脆做個現場預覽沙盒(剛好 Storybook 這類工具當時已經蠻流行),結果滿多人都覺得有點道理。不久之後,就出現了能即時切換品牌視覺、模擬特殊狀況(像文字暴長或暗色模式)、甚至連 QA 都拿來驗證樣式變動的小工具。還記得測試階段,有將近三分之一的新問題,其實就是靠這種預覽才提前抓到。不僅工程師覺得省事,連非技術背景的人也樂於參與討論,看起來對縮短溝通周期確實有幫助。
說到底,「主題化」並不是單純換皮膚那麼輕鬆;這背後更多是在架構層面的思考。如果只當它是 CSS 小事,很容易忽略那些深層系統性的需求。不過,每家公司做法都不盡相同,上述經驗頂多算是一種嘗試吧,有些細節恐怕也未必適合所有場景。
有時候設計師和工程團隊會聊到「分離設計跟邏輯」這個話題,常聽到有人說 token 怎樣怎樣,但到底是什麼時候開始,這些東西才真的有明顯差異呢?大概在多品牌支持的情境下吧。當初 plugin 類型的覆寫,其實就讓各家品牌的客製都被包得緊緊的,不會彼此干擾。像是預覽工具啊、一些測試環境,其實也讓非工程師的人比較容易上手,大致是這樣。
突然想到,當一個產品同時要滿足很多不同品牌需求,很容易會出現那種「如果品牌等於誰誰誰」這種巢狀條件,看久了還真有點頭暈。如果一直放任不管,代碼可能會變得很難整理,也容易出錯。所以,那陣子有個做法,就是用一套結構化的功能旗標(feature flag)策略去處理,各家品牌要開關什麼功能,都能自己決定,而且還能慢慢地漸進式釋出,不必一次全開或全關。
後來搞了一份中央註冊表,把所有功能旗標都掛在那裡,每一項都有個名字和說明,有些功能預設是打開,有些則反過來。例如像「啟用雙向訊息」這類設定,好像預設就是開著;「顯示會員積分」那塊則通常沒啟動。程式跑起來時,每個品牌可以根據自己的需求蓋掉預設值。
其實大家最怕就是 feature flag 用到哪都是小段 if else 到處亂飛。那次專案乾脆把旗標判斷包成一支 hook,大家只要問 isEnabled 就知道結果,想追蹤紀錄、加點分析數據也方便很多,有種所有資訊都集中管理的感覺。
說起來還蠻重要的一點,是整套機制在運作中並不允許隨意改動旗標內容,不然如果線上應用突然變動,就可能導致那些難以追查的小 bug 或 race condition,所以後來也算謹慎地把旗標做成唯讀狀態。雖然每家團隊操作習慣略有不同,但基本上只要遵循這種方式,好像就能比較減少混亂,也方便日後維護吧。
突然想到,當一個產品同時要滿足很多不同品牌需求,很容易會出現那種「如果品牌等於誰誰誰」這種巢狀條件,看久了還真有點頭暈。如果一直放任不管,代碼可能會變得很難整理,也容易出錯。所以,那陣子有個做法,就是用一套結構化的功能旗標(feature flag)策略去處理,各家品牌要開關什麼功能,都能自己決定,而且還能慢慢地漸進式釋出,不必一次全開或全關。
後來搞了一份中央註冊表,把所有功能旗標都掛在那裡,每一項都有個名字和說明,有些功能預設是打開,有些則反過來。例如像「啟用雙向訊息」這類設定,好像預設就是開著;「顯示會員積分」那塊則通常沒啟動。程式跑起來時,每個品牌可以根據自己的需求蓋掉預設值。
其實大家最怕就是 feature flag 用到哪都是小段 if else 到處亂飛。那次專案乾脆把旗標判斷包成一支 hook,大家只要問 isEnabled 就知道結果,想追蹤紀錄、加點分析數據也方便很多,有種所有資訊都集中管理的感覺。
說起來還蠻重要的一點,是整套機制在運作中並不允許隨意改動旗標內容,不然如果線上應用突然變動,就可能導致那些難以追查的小 bug 或 race condition,所以後來也算謹慎地把旗標做成唯讀狀態。雖然每家團隊操作習慣略有不同,但基本上只要遵循這種方式,好像就能比較減少混亂,也方便日後維護吧。

如果講到一開始實驗或分階段上線的時候,旗標這種東西,大部分情況下都是預先寫進每個版本裡,好像只要有需要還能用遠端設定稍微調一下。那有人會問,為什麼不是直接全部都靠 Remote Config 搞定呢?說真的,一開始大家比較偏好在編譯時就決定好開關,覺得這樣比較單純又不容易出狀況。後來產品慢慢長大了,才陸續加進 Firebase 那套遠端設定系統——像是臨時想做個新 UI 的 A/B 測試、遇到哪個功能突然爆雷(這種事情聽說也發生過幾次),或者某些地區法規忽然改變,需要趕快調整合規條件之類的場合,就會特別派上用場。雖然說兩種方式混著用,有點雜,但從測試到正式上線,其實讓大家心裡踏實不少,也保留了一點彈性。
接下來聊聊自動化部署。有的人可能覺得維護一款手機 App 已經夠頭疼了,可是當品牌數量超過手指數幾倍,每個品牌圖片、設定檔、更新時間全都不同……光想就覺得有點複雜。如果還想靠人工去包版,不太現實啦,所以團隊算是很早就砸蠻多資源搞 CI/CD,自動化流程多少幫助保持秩序。有些人提過我們搞那套「懂品牌」的建置流程,是 GitHub Actions 加上一些自己寫的小工具和腳本組起來的。其實細節比外面傳聞再亂一些——畢竟每間公司的情境都差不多,解法也沒有哪一招一定適合所有人,只能看需求不停修修補補罷了。
接下來聊聊自動化部署。有的人可能覺得維護一款手機 App 已經夠頭疼了,可是當品牌數量超過手指數幾倍,每個品牌圖片、設定檔、更新時間全都不同……光想就覺得有點複雜。如果還想靠人工去包版,不太現實啦,所以團隊算是很早就砸蠻多資源搞 CI/CD,自動化流程多少幫助保持秩序。有些人提過我們搞那套「懂品牌」的建置流程,是 GitHub Actions 加上一些自己寫的小工具和腳本組起來的。其實細節比外面傳聞再亂一些——畢竟每間公司的情境都差不多,解法也沒有哪一招一定適合所有人,只能看需求不停修修補補罷了。
每個應用程式,說來也沒什麼特別的魔法,各自有自己的建置指令。像是要換主題或功能設定、圖示、啟動畫面、名稱,甚至那些 firebase 的憑證、環境變數,大致上都會在這步驟裡弄進去。有時候一行指令就能搞定——比如輸入某個品牌名稱,還有目標平台,然後那串長長的 yarn 指令就開始跑。想再多加一個新品牌?大概只需要放進新的設定檔,也許不用擔心太多流程問題。
倒是在正式讓 app 上線之前,他們似乎會先跑一輪自動檢查。一些細節,比如缺了什麼色彩或圖片、有些設定互相衝突……大部分情況下,早期這種自動檢查能攔下將近九成可能出錯的狀況,所以後面品保流程壓力沒那麼大,不太容易臨時出現火燒屁股的事。不過偶爾還是有漏網之魚啦。
另外有件事蠻常見,有些合作方或者品牌的人希望提前看到成果,不想等到真正上市才知道長什麼樣。所以,每個品牌通常都會有專屬的預覽包版本,用 TestFlight 或 Firebase 讓人下載試用。這些預覽包通常會附上一點釋出說明,有 QR code 可以直接掃描下載,有時候還能先看幾張主要畫面的快照。對於不是工程師背景的人來說,這種方式也許比較直觀,比起反覆討論修改需求,好像少了不少麻煩。
至於發佈 app 到商店,那邊他們倒是用了 fastlane 自動化工具,所以不管是 iOS 還是 Android,上傳檔案、更新截圖描述文案、通知團隊成功與否,大致都交給腳本跑了。這樣工程師手邊比較能空出時間做其他功能開發,也比較容易維持各品牌同步更新。不過所有事情都如此順利,好像也只是偶爾而已吧。
倒是在正式讓 app 上線之前,他們似乎會先跑一輪自動檢查。一些細節,比如缺了什麼色彩或圖片、有些設定互相衝突……大部分情況下,早期這種自動檢查能攔下將近九成可能出錯的狀況,所以後面品保流程壓力沒那麼大,不太容易臨時出現火燒屁股的事。不過偶爾還是有漏網之魚啦。
另外有件事蠻常見,有些合作方或者品牌的人希望提前看到成果,不想等到真正上市才知道長什麼樣。所以,每個品牌通常都會有專屬的預覽包版本,用 TestFlight 或 Firebase 讓人下載試用。這些預覽包通常會附上一點釋出說明,有 QR code 可以直接掃描下載,有時候還能先看幾張主要畫面的快照。對於不是工程師背景的人來說,這種方式也許比較直觀,比起反覆討論修改需求,好像少了不少麻煩。
至於發佈 app 到商店,那邊他們倒是用了 fastlane 自動化工具,所以不管是 iOS 還是 Android,上傳檔案、更新截圖描述文案、通知團隊成功與否,大致都交給腳本跑了。這樣工程師手邊比較能空出時間做其他功能開發,也比較容易維持各品牌同步更新。不過所有事情都如此順利,好像也只是偶爾而已吧。

其實設計可擴展的白標行動系統,說到底不只是技術層面的事,有時候反而是思維的轉換——彷彿團隊一下子要重新學習什麼叫「彈性」和「維護」,還有那種產品推進速度。以前總覺得只要讓程式碼能跑就好,後來才慢慢發現,如果哪裡都充滿複雜度,大家根本沒辦法好好維護。有人建議過,把那些客製化的東西盡量分開處理,不然大概過了一段時間,就會搞得像毛線糾結一樣難解。
偶爾也聽到不同團隊在討論,到底應該把這些專案看成平台?還是純粹當作單一應用?其實蠻多經驗告訴我們,如果想長久經營,大概還是得往平台方向靠攏。不只是寫程式,更常需要投入一些精力在工具、文件,甚至開發人員體驗這類比較容易被忽略的小細節上。有些人說這樣會拖慢速度,但遇過幾次交接混亂後,好像又不得不承認,多花點心思通常比較保險。
自動化流程也是類似情況,一開始就導入持續整合、持續部署,其實對日後管理白標版本來說,省下不少麻煩。之前碰到過沒有自動化時,每次改版都像臨時救火,大概不到一半的人能順利跟上。所以現在回頭看,早點做這件事情可能更輕鬆。
至於靈活度,有個說法倒挺有趣:不是所有東西都非得開放給用戶或合作夥伴調整。有時候訂下一些限制或規則,反而讓團隊走得更快,也減少了莫名其妙的錯誤。畢竟選擇太多,有些新手工程師可能會花掉將近一半時間在試各種組合,到最後連自己也搞不清楚初衷。本來以為全面自由最好,但現在越來越多人傾向適度加點防護欄。
總之,這樣一路摸索下來,大致可以感受到——每個決定背後都有取捨,也許沒有所謂絕對正確的方法,只是在不同場景下找到適合當下狀態的一種平衡吧。
偶爾也聽到不同團隊在討論,到底應該把這些專案看成平台?還是純粹當作單一應用?其實蠻多經驗告訴我們,如果想長久經營,大概還是得往平台方向靠攏。不只是寫程式,更常需要投入一些精力在工具、文件,甚至開發人員體驗這類比較容易被忽略的小細節上。有些人說這樣會拖慢速度,但遇過幾次交接混亂後,好像又不得不承認,多花點心思通常比較保險。
自動化流程也是類似情況,一開始就導入持續整合、持續部署,其實對日後管理白標版本來說,省下不少麻煩。之前碰到過沒有自動化時,每次改版都像臨時救火,大概不到一半的人能順利跟上。所以現在回頭看,早點做這件事情可能更輕鬆。
至於靈活度,有個說法倒挺有趣:不是所有東西都非得開放給用戶或合作夥伴調整。有時候訂下一些限制或規則,反而讓團隊走得更快,也減少了莫名其妙的錯誤。畢竟選擇太多,有些新手工程師可能會花掉將近一半時間在試各種組合,到最後連自己也搞不清楚初衷。本來以為全面自由最好,但現在越來越多人傾向適度加點防護欄。
總之,這樣一路摸索下來,大致可以感受到——每個決定背後都有取捨,也許沒有所謂絕對正確的方法,只是在不同場景下找到適合當下狀態的一種平衡吧。
有時候,白標系統要做得好,真的不只是換個商標那麼簡單。其實最早開始時,好像也沒想太多,只是想說讓用戶方便點。但後來,慢慢發現那種模組化、誰負責什麼、流程清楚這些東西,其實都還挺關鍵。有些人會說,這套架構支撐住了客戶需求,也讓公司規模拉大了不少——差不多有七成左右的使用者反饋感覺還不賴,但也不是每一個場景都能完全照用。當初在設計,每個小決策其實多少都跟「這到底對生意有沒有幫助」脫不了關係。
而且,有時候我們討論到品牌表達,那個邏輯其實比單純外觀切換複雜很多。有人覺得只是在系統裡面調個顏色、改幾行字就算數,可事實上可能得花上好多天來溝通細節,才不至於搞錯方向。如果基礎打好了,它確實能促進產品成長跟建立用戶信任,不過,也不是隨便弄弄就會自動見效啦。偶爾還會遇到一些很難界定的問題,比如權限分工啊、維護責任啊之類的,處理起來總免不了反覆協調。
結果看下來,好像也不能光說是「成功」或「失敗」。倒是蠻多人注意到,這樣的系統讓公司多了一點彈性,如果哪天要再擴展新合作夥伴,大致上也不會太手忙腳亂。所以說到底,它比較像是一台支持品牌各自發揮的小引擎,而不是大家以為那種千篇一律的模板。如果真要講什麼經驗,大概就是選擇方向時盡量別脫離業務目標吧;其他細節,就只能邊走邊修正了。
而且,有時候我們討論到品牌表達,那個邏輯其實比單純外觀切換複雜很多。有人覺得只是在系統裡面調個顏色、改幾行字就算數,可事實上可能得花上好多天來溝通細節,才不至於搞錯方向。如果基礎打好了,它確實能促進產品成長跟建立用戶信任,不過,也不是隨便弄弄就會自動見效啦。偶爾還會遇到一些很難界定的問題,比如權限分工啊、維護責任啊之類的,處理起來總免不了反覆協調。
結果看下來,好像也不能光說是「成功」或「失敗」。倒是蠻多人注意到,這樣的系統讓公司多了一點彈性,如果哪天要再擴展新合作夥伴,大致上也不會太手忙腳亂。所以說到底,它比較像是一台支持品牌各自發揮的小引擎,而不是大家以為那種千篇一律的模板。如果真要講什麼經驗,大概就是選擇方向時盡量別脫離業務目標吧;其他細節,就只能邊走邊修正了。
參考來源
想「轉行」靠寫程式吃飯嗎?一個自學程式語言幾乎將自己逼 ...
軟體工程師薪水正在逐年攀升中,2014年軟體工程師的平均年薪達$97098美元(台幣三百萬)之高1,學習寫程式的熱潮更是席捲全球,下自8歲上自80歲每天都 ...
來源: 風傳媒升級打怪自己來-YYSports 跑步App 使用全指南| 文章| 運動筆記
「跑步遊戲化」這個概念就在我的腦海裡盤旋不去,而最近我發現了一款新的App-YYSports。就是一款把跑步遊戲化概念帶到跑步App 使用情境中的軟體,橫豎我每天都要運動,就 ...
來源: 運動筆記
相關討論