js中面向物件的簡單應用;前後設計對比。
先一步步剖析需求!
場景如圖:
這樣看來需求如下:
頁面上輸入金額,並顯示到右下角。
然後開啟抽屜,抽屜裡面顯示可用金額和已用金額,可用金額預設等於總金額。
然後抽屜裡面輸入金額的時候,可用金額減少,已用金額增加。
所以一開始是這樣設計的:
1、在dva的model裡面定義了三個金額欄位,分別為 totalAmount、availableAmount、usedAmount
2、在第一個輸入金額的框那裡,直接通過dispatch儲存最新的值進去。大概是這樣
dispatch({ type: 'xxx/save', payload: { totalAmount: '輸入框的值' } })
3、將totalAmount顯示到頁面上
4、開啟抽屜,初始化時,availableAmount =totalAmount;usedAmount = 0;
5、填寫第二個金額輸入框,同理直接使用dispatch更新
dispatch({ type: 'xxx/save', payload: { availableAmount: totalAmount - '輸入框的值', usedAmount: '輸入框的值' } })
6、將這個兩個金額顯示到頁面上。
至此就實現了上訴效果。然而,事情可能並沒有那麼簡單........
新需求如圖:
需求加了兩個Icon,一個新增,一個刪除。
意思就是Input框是批量的,那就是說,會有無數個地方更新金額,並且我不能直接使用「輸入的值」,而是需要先進行彙總計算。
所以,這個時候我把這兩個dispatch的邏輯分別提了兩個公共的方法出來。放在了它們所在的元件當中。
方法大概是這樣
const setTotalAmount = (amount) => { dispatch({ type: 'xxx/save', payload: { totalAmount: '新的值' } }) } /** * * @param {number} amount 抽屜裡面所有輸入框值的求和 */ const setAvailableAmountAndUsedAmount = (amount) => { dispatch({ type: 'xxx/save', payload: { availableAmount: totalAmount - amount, usedAmount: amount } }) }
end~
功能實現了,但是有些問題:
- 金額欄位在model裡面,更新值的方法在對應的兩個元件中,程式碼邏輯不清晰,不方便閱讀和管理。
- 不可重用,後期如果有同樣的場景,需要再寫一遍。
果然。事情就這樣過了幾個月,另外一個模組出現的同樣的需求場景。
我開始思考這個問題,那麼我還得按照同樣的方式,再在model中定義三個amount欄位,然後再寫兩個方法來更新它???
如果我不寫寫一套一樣的,用同一套model和欄位,那麼資料在流轉的過程中,是不是就混淆在一起了呢?
如果把它抽象成一個類Amount
它的狀態是:總金額、可用金額、已用金額。
它的行為是:更新總金額、更新可用和已用金額。
那現在開始編class Amount // 總金額 totalAmount = 0;
class Amount { // 總金額 totalAmount = 0; // 可用金額 availableAmount = 0; // 已用金額 usedAmount = 0; constructor(defaultAmount) { // 當頁面回顯的時候,可以直接通過預設值來初始化 this.totalAmount = defaultAmount ?? 0; } /** * @param {number} amount 總金額 */ setTotalAmount(amount) { this.totalAmount = amount; this.availableAmount = amount; } /** * @param {number} amount 已使用金額 */ setAvailableAndUsedAmount(amount) { this.availableAmount = this.totalAmount - amount; this.usedAmount = amount; } getTotalAmount() { return this.totalAmount; } getAvailableAmount() { return this.availableAmount; } getUsedAmount() { return this.usedAmount; } }
使用:
- 開啟頁面的時候 const amount = new Amount()
- 輸入金額的時候amount.setTotalAmount(100)
- 顯示的時候amount.getTotalAmount()
- 開啟抽屜,預設顯示 amount.getAvailableAmount(); amount.getUesdAmount()
- 輸入金額的時候 amount.setAvailableAndUsedAmount()
程式碼很簡單,比教材裡面的demo都還要簡單。但是它解決了上面的痛點:
- 金額的計算和顯示功能,統一管理,邏輯清晰。
- 程式碼重用,每次只需要 new 一個 amount物件