三個訣竅優化前端開發者體驗 從 UI/UX 來解析好讀的程式碼

me
林彥成
2021-04-16 | 3 min.
文章目錄
  1. 1. 程式碼 SEO
  2. 2. 單一功能原則
  3. 3. 方便重構的設計

什麼是開發者體驗(Developer Experience)?

開發者體驗其實就是從 UI/UX 來評估開發者的日常行為,其中開發者的使用者介面 (User Interface) 就是程式碼,而好的使用者體驗(User Experience) 除了包含了好的使用者介面外,開發環境提供語法高亮、自動完成等功能也是重要的環節。

對開發者來說,常見的使用者情境大多為加新功能、修正問題、極端案例測試三種

  1. 加新功能: 找到適合的位置後加上對應程式碼且沒有增加新的問題
  2. 修正問題: 找到問題在程式碼中的位置,修正並測試且沒有增加新的問題
  3. 極端案例測試: 找到發生位置並測試極端值是否會讓程式碼不正常運作

可以發現開發者會不斷進行 “尋找” → “閱讀” → “修改” 的過程,所以接下來也分成三個部份來進行優化

  1. 程式碼 SEO: 優化尋找
  2. 單一功能原則: 優化閱讀
  3. 方便重構的設計: 優化修改

程式碼 SEO

當需要修改時,相關的程式碼好找嗎? 會不會找到很多無關的程式碼放在一起? 舉例來說我們就可以將相近功能的程式都放在一起,這樣直觀的設計能夠更快的幫助新進人員進入專案協助。

1
2
3
4
5
6
7
├── Login/
│ ├── SocialButton/
│ │ ├── LineButton.js # 社群登入的 Line 按鈕
│ │ └── FacebookButton.js # 社群登入的 FB 按鈕
│ ├── Modal/
│ │ └── ModalLogin.js # 登入的 Modal
│ └── index.js # 登入邏輯與主要 Layout

對工程師來說,會忘記之前寫的東西在哪是很合理的,所以在 IDE 有支援搜尋的前提下,我們就需要針對程式碼做一定程度的 SEO,一個最棒的搜尋結果就是當使用者輸入一個關鍵字後只會得到一個最適合的結果。

舉例前端的例子來說,一般團隊有可能會使用 BEM 的命名規則,像是 info__title 這樣代表我們設定的是訊息的標題,所以當進行搜尋時 info__title 就會是我們的關鍵字,如果是底下示範的第一種寫法反而會造成開發者的困擾。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Bad 用 .info 才能找,且找到後還要再找第二層
.info {
height: 100%;
margin: 1% 2%;
&__title {
padding: 1% 0 1% 2%;
color: white;
}
}

// Good 大多情境可一次就找到
.info {
height: 100%;
margin: 1% 2%;
.info__title {
padding: 1% 0 1% 2%;
color: white;
}
}

單一功能原則

單一功能原則 (Single responsibility principle) 的目的是減少同個區塊中不相關的邏輯。

當被開發者找到程式碼後,可以更快確認在哪一行產生目前的行為,更容易去判斷在這一階層 (頁面) 的操作只要正確就可以不用煩惱其他階層的任何操作,進而更容易且安全的去修改程式碼。

以撥放器的 App 來說,撥放的頁面和設定的頁面是分開的,設定的時候並不用管撥放的時候做了什麼操作,對程式碼來說開發者就要知道這段程式碼是在做什麼,有沒有耦合或是在不明顯的地方又多做其他的事情,以 React 的開發來說比較好的方式就是將顯示邏輯和資料邏輯分開。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import React, { useState } from 'react';
// 資料和顯示寫在一起
function SendButton() {
const [data, setData] = useState(null);
const strButtonDisplay = '送出';
const url = 'http://example.com/movies.json';
// 送出的邏輯
function handleSend() {
fetch(url)
.then((response) => {
return response.json();
})
.then((myJson) => {
setData(myJson);
});
}
return (
<button type="button" onClick={handleSend}>
{strButtonDisplay}
</button>
);
}

// 將資料和顯示邏輯分開
// 資料邏輯
function useSubmit({ strButtonDisplay, url }) {
const [data, setData] = useState(null);
function onClick() {
// 送出的邏輯
fetch(url)
.then((response) => {
return response.json();
})
.then((myJson) => {
setData(myJson);
});
}
return {
strButtonDisplay,
data,
onClick,
};
}

// 顯示邏輯
function ThemeButton() {
const { strButtonDisplay, data, onClick } = useSubmit({
strButtonDisplay: '送出',
url: 'http://example.com/movies.json',
});
return (
<button type="button" onClick={onClick}>
{strButtonDisplay}
</button>
);
}

方便重構的設計

方便重構的設計代表程式碼有多方便被修改,那是否有機會運用開發工具進行驗證和加速重複運用程式碼的過程?

  1. 方便重構的設計,我個人認為盡量用布林值會更方便,舉例來說隱藏的條件就可以用 isVisible 或是 isDisable 的布林值來控制條件渲染。
1
2
3
4
5
function getNowElement({ isVisible, isDisable }) {
const isHidden = !isVisible || isDisable;
if (isHidden) return null;
return <span>show</span>;
}
  1. 方便閱讀的命名

雖然布林值算好讀,但當命名和布林值寫在判斷式中時,會發現我們還是需要進行思考,也較不直觀,底下舉了兩種例子,可以發現第二種命名來說就會更直觀一些。

1
2
3
4
5
6
7
8
9
const VISIBLE = true;
const HIDDEN = false;

// 需要稍微思考
if (element.visible === true)

// 幾乎不需要思考
if (element.visibility === VISIBLE)
if (element.visibility === HIDDEN)
  1. 目的明確的命名

在命名的目的上也需要更明確一些可以減少過多的閱讀理解,舉個按鈕的例子來說:

  • 確定 (OK)/取消 (Cancel): 使用者確定了什麼取消了什麼
  • 送出 (Send)/繼續編輯 (Keep Editing): 可以推測出是送出文章和取消送出且繼續編輯

喜歡這篇文章,請幫忙拍拍手喔 🤣

share