上次我們已經把基本記帳功能都完成了,版型調整也都差不多了(雖然折騰許久),當然是緊接著下一個功能囉!
回頭看一下之前寫的使用者故事:
作為一個 [重度記帳軟體的使用者],
我想要 [單手完成記帳操作],
以便 [節省記帳時間且避免忘了記帳]。
當初覺得這樣好像很具體,但現在回頭來看這一則使用者故事,才發現「單手完成記帳操作」這個項目有點太抽象了。
單手,是誰的單手,是哪隻手? 記帳操作包含哪些行為? 在釐清這些疑問之前,很難繼續表列詳細的需求,更別說程式碼了;而就算硬著頭皮「照想像」那樣來獵需求,接著趕工寫程式做出來,很大機率不是使用者想要的東西。
總之,首先是先拆解使用者故事,回頭將沒這麼具體的需求給補上,至少要有比較明確的「可驗收標準」才行。
第一個就是「單手」操作,單手是誰的手? 多大的手? 如果不弄清楚這項需求,否則一個「手超小」的朋友來用 App ,說沒有辦法單手操作,這項需求就沒有滿足了。
所以得先設定一個標準來設定驗證目標,這邊姑且就先以我的手為「目標使用者」的手。
會這麼做,是我的手偏小(客觀來說),既然我都能夠單手完成操作,那大部分的人應該也都可以。另外我是右撇子,所以整個需求組合起來,就會像是這樣:
「偏小的右手可以單手操作」:
可以單手操作完成記帳,
先訂「以我右手能夠單手操作完成為標準」的驗收條件。
好,「單手」的需求大致上確定了,那另外一個是「完成記帳」的需求有待釐清。
怎樣才會「完成」記帳? 有人會想說可以輸入金額的詳細用途,還有支付方式…等,才算是完整的一筆記帳,唯有完成了這些,帳目才算紀錄完成。
先前只完成了這樣的記帳功能,只能輸入金額記帳,只看得到每筆帳目金額。但若是參考現有的記帳 App,至少都還會有「帳目類別」,可以紀錄該筆金額是花在哪裡。
如下圖參考的記帳 App 所示
左邊是卡娜赫拉記帳 App,右邊是 Ahorro。
我們可以看到,兩款記帳 App 都能夠選擇「分類」,一個是按鈕再點進去做選擇,另一個則是直接呈現在畫面第一層(早餐、午餐、晚餐…等類別 icon 按鈕)。此外,甚至還可以做帳目的備註。
而以我這個記帳重度使用者來說,「最必要」的是選擇帳目的類別,我會需要知道某一段時間,各類別的花費金額是多少,依照類別統計帳目的金額。
如果把這項需求化為使用者故事的話,會像是這樣
作為一個 [記帳軟體的使用者],
我想要 [紀錄賬目種類],
以便 [區分不同帳目之金額以易於理財]。
既然其他記帳 App 有做這項功能,而自己(使用者)也會有需要。因此可以推論這項功能確實有新增的必要,可以說是此功能算這類軟體的「最低標準」之一,有了之後,使用者才會用。
A && B
,代表兩者都要為真,結果才為真。有學過計算機概論的各位,想必都知道這是一種邏輯運算子。
為什麼要講這些? 因為要把比較大範圍的任務,切成較小單位的任務單元,這樣才好釐清需求並且精準地跟 AI 下指令。
而今天的這個需求:單手操作且可以選擇種類
,寫成邏輯運算子的方式便是:
「單手操作」 && 「選擇種類」,需兩者都有達成,才算滿足需求,所以可以將其切成兩個小任務。
選擇種類的部分,依照「單手操作」的需求,將其至於底部,這樣才方便「單靠右手就能操作」,而不必另一隻手拿著手機才能做到。
做出來的設計稿,長得像這樣。右邊是選擇種類的 UI,是在原本填寫數字之後,按下 OK 再多一步,讓使用者可以選擇帳目的類型。
這樣 AI 有辦法看得懂嗎? 我…我是不太相信啦 😂
不過還是先丟給 AI 試試看,不試白不試,反正產出的不是我們要的程式碼,那就算了。因為是比較複雜的需求,用了 Claude-3.5-sonnet 模型來負責產程式碼。
請幫我根據設計稿,在原有的記帳 App 中,新增一步
- 輸入數字之後,按下 OK ,會出現選擇類別的畫面
- 選擇類別(飲食、日用品...等)之後,並按下 OK,才會紀錄該筆帳目。
把 AI 產的程式碼做 Apply ,令人意外的,AI 寫得還不錯!?
撇除顏色問題以外,該做到的功能與流程,像是輸入金額之後,會進到選擇種類這一步,這部分 AI 都有幫我做到!(還是想小小抱怨一下,AI 為什麼要把我寫好的藍色給改掉,是不是不喜歡設計稿的藍… 😢)
仔細品味一下功能,列一下 AI 「沒有」做到的事:
如果把指令拆解成更小的步驟,AI 會做得更好嗎?
步驟拆成個別小指示,請 AI 「亦步亦趨」幫我們完成功能(這裡套用了敏捷開發的精神,多迭代小步驟增量)
指令步驟如下所示
我要在這個記帳 App 新增「選擇種類」的功能,如設計稿所示
- 種類可以選擇 8 種,目前介面上的種類僅為參考
- 在輸入數字之後,按下 OK,便會跳出選擇種類的介面。
- 種類被選取後,會有橘色框線醒目提示
- 按下 OK 做了確認,該項記帳才會被記錄下來
這次把指令給了詳細點,拆成多步驟且舉例詳細,等了一會後,AI 給了這樣的結果:
interface CategorySelectorProps {
onSelectCategory: (category: string) => void;
onCancel: () => void;
pendingAmount: number;
}
const CategorySelector: React.FC<CategorySelectorProps> = ({ onSelectCategory, onCancel, pendingAmount }) => {
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const categories = ["飲食", "日用品", "娛樂", "交通", "服飾", "醫療", "教育", "其他"];
const handleCategorySelect = (category: string) => {
setSelectedCategory(category);
};
const handleConfirm = () => {
if (selectedCategory) {
onSelectCategory(selectedCategory);
}
};
//...
const App: React.FC = () => {
// ... 保留原有的 state 和其他函數 ...
const handleOk = () => {
const amount = parseFloat(currentAmount);
if (!isNaN(amount)) {
setPendingAmount(amount);
setShowCategorySelector(true);
}
setCurrentAmount("0");
};
const handleSelectCategory = (category: string) => {
if (pendingAmount !== null) {
setTotal(total + pendingAmount);
setHistory([...history, { amount: pendingAmount, category }]);
setPendingAmount(null);
}
setShowCategorySelector(false);
};
const handleCancelCategorySelection = () => {
setPendingAmount(null);
setShowCategorySelector(false);
};
光看程式碼的部分,可以知道這次種類的資料,是真的有給到 8 種之多;且不是按了種類就直接記帳,需要點擊 OK(handleConfirm)才會確認記帳。
以下實際展示 AI 生成的程式碼畫面,看起來確實幫我把功能完成了!!選擇種類並按下 OK 才會記帳,這點最核心的部分也如預期完成。至於單一帳目有紀錄種類的功能,也一樣沒有遺漏,很棒!
儘管一些小細節沒有處理好,像是 UI 部分的對齊、樣式細節和版面配置並沒有如設計稿一樣,但這都是小問題,瑕不掩瑜!
寫出好 Code 是不容易,但沒有比釐清真正的需求要做什麼還難。
幾年的開發經驗以來,花最多的時間不是搞懂要怎麼寫(程式碼),而是搞清楚「為什麼」使用者想要這樣,釐清需求中比較模稜兩可的部分。
而釐清之後,最後還要將需求拆解成「任務」,再落地轉化成小小一項的 Todo 清單。這不只是開發的基本,在與生成式 AI 的協作上更是不可或缺。上面透過需求的「再解析」給大家示範了,提出明確且小量資訊脈絡的功能需求,AI 的生成精準度大幅提升,生成的程式碼便變得相當可靠且立即可用!