一個是客戶填的,一個是系統算的。混在一起就會爛。


購物車最常見的設計錯誤,是只有一個「購物車物件」。

那個物件裡面同時有 items、coupon,也有 subtotal、discount、total、gifts。它從 session 讀出來、被 controller 改、再存回 session。改久了沒有人知道裡面哪些欄位是「客戶選的」、哪些是「算出來的」,也沒有人知道那份 total 是什麼時候算的、還準不準。

我的做法是拆成兩個物件,而且它們的生命週期完全不同。

CartInput:客戶意圖,會被儲存

items    sku => 數量
coupon   折扣碼
addons   sku => 數量
points   想折抵的點數
note     訂單備註

全部都是客戶按出來的東西,一個金額欄位都沒有。

它的生命週期是「跟著 session 走」,客戶三天沒回來,它還在。所以它必須是那種放三天也不會過期的資料——SKU 跟數量放三天沒問題,total 放三天就是錯的。

操作它的方式是回傳新物件:

CartInput ──addItem / withCoupon / removeAddOn──▶ CartInput

CartState:計算狀態,用完就丟

lines             CartLine[](帶 name、unitPrice,從 DB 撈出來的)
adjustments       Adjustment[](折扣 / 加價)
gifts             Gift[]
addOns            CartLine[]
pointsEarned / pointsRedeemed

它的生命週期是「這一個 request」。要顯示購物車、要結帳,就從 CartInput 撈 DB、組一份全新的 CartState,跑完計價 pipeline,用完丟掉。永遠不存回 session、不存進任何地方。

CartInput ──(撈 DB)──▶ CartState ──pipeline──▶ CartState'

為什麼一定要分開

因為儲存的東西必須能放很久,計算的東西必須夠新。 這是兩個互相衝突的要求,一個物件滿足不了。

分開之後,很多問題自動消失:

  • 商品改價、活動下檔,購物車自動反映最新狀態,因為 CartState 每次重建。
  • 沒有「快取失效」的問題,因為根本沒有快取。
  • 不會出現「session 裡有贈品,但實際結帳沒送」的分歧,因為贈品從來不在 session 裡,它是每次算出來的。

還有一個很容易被忽略的差別:同一個概念,兩邊各有一份,而且不一樣。

點數就是例子。CartInput 有 pointsToRedeem(客戶「想」折抵多少),CartState 有 pointsRedeemed(pipeline 夾制後「實際」折抵多少)。

客戶輸入 5000 點,但他只有 800 點、而且上限是訂單金額的 20%,最後實際折抵 600。這時 session 裡存的仍然是 5000——因為那就是他的意圖。等他之後又加購了幾件商品,金額上去了,同一個意圖自然就折得更多。

如果只有一個物件,你就得在客戶輸入的當下把 5000 夾成 600 存回去,然後他加購之後點數莫名其妙不會變多,還得寫一堆補救邏輯。

意圖跟結果是兩件事,就給它們兩個物件。


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA

共有 0 則留言


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA
🏆 本月排行榜
🥇
站長阿川
📝45   💬1  
643
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次