Code Review 首要達成的結(jié)果是更好的可讀性兽叮。
在此基礎(chǔ)上才是進一步發(fā)現(xiàn)項目的 Bug充择、處理性能優(yōu)化上的問題匪蟀。
因為,編碼是給人看的观挎,不是給計算機(Coding for human, NOT computer)嘁捷。
一. 濫用縮寫命名 Overusing abbreviation
大部分業(yè)務(wù),尤其是不是直接暴露在前端的業(yè)務(wù)显熏,不需要考慮混淆的設(shè)計雄嚣,別因為少打兩個字,讓你的同伴都搞混了喘蟆!
# Bad. 自成體系的縮寫
lst = [1, 2, 3, 4, 5]
sqrd_lst = [num**2 for num in lst]
fltd_sqrd_lst = list(filter(lambda x: x % 2 == 0, sqrd_lst))
# Good. 一眼看出變量名的含義
riginal_numbers = [1, 2, 3, 4, 5]
squared_numbers = [num**2 for num in original_numbers]
filtered_squares = list(filter(lambda x: x % 2 == 0, squared_numbers))
二. 語法糖可能是毒藥 Syntax Sugar can be Poison
語法糖是常見的程序員炫技手段缓升,但即使對寫下這段代碼的人,經(jīng)過一段時間后蕴轨,也未必能在第一時間讀出這段代碼的含義港谊。
例如在 Python 中:
-
使用布爾操作符作為條件判斷
第一段炫技代碼,不熟悉的同學(xué)可能第一反應(yīng)是result=True
# 炫技橙弱,可讀性差
is_valid = True
result = is_valid and "Valid" or "Invalid"
# 等價歧寺,可讀性更好
result = "Valid" if is_valid else "Invalid"
- 使用列表推導(dǎo)式處理嵌套列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
-
過度追求“簡潔”的 lambda 表達式
lambda 表達式用在 sorted 中做為排序參數(shù)是比較常用的,但過度追求單行表達棘脐,是不可取的蛀缝,除了可讀性差蕴潦,還違背了程序設(shè)計的單一職責(zé)原則忽冻。
單行僧诚、可讀性差版本:
students = [
{"name": "Alice", "age": 25, "grade": 90},
{"name": "Bob", "age": 22, "grade": 85},
{"name": "Charlie", "age": 28, "grade": 88}
]
sorted_students = sorted(students, key=lambda x: (lambda y: (lambda z: z["grade"] - y["age"])(y))(x))
分離職責(zé)蹦骑,可讀性好版本:
def calculate_score(student):
return student["grade"] - student["age"]
sorted_students = sorted(students, key=calculate_score)
當(dāng)然边败,語法糖也有少部分是增加可讀性的,可以作為代碼規(guī)范使用:
big_number = 1_000_000_000
# equivalent to big_number = 1000000000
1 < x < 10
# equivalent to 1 < x and x < 10
三. 不可預(yù)測的代碼 Unpredictable Code
好代碼是可預(yù)測的,壞代碼是給人驚嚇的断傲。
一種是由于開發(fā)人員基礎(chǔ)不扎實無意識造成的:
例如:
使用可變變量作為參數(shù)
# WRONG:
def add_numbers(a, b, result=[]):
result.append(a + b)
return result
# Example usage
print(add_numbers(1, 2)) # Output: [3]
print(add_numbers(3, 4)) # Output: [3, 7]
print(add_numbers(5, 6)) # Output: [3, 7, 11]
# CORRECT:
def add_numbers(a, b, result=None):
if result is None:
result = []
result.append(a + b)
return result
# Example usage
print(add_numbers(1, 2)) # Output: [3]
print(add_numbers(3, 4)) # Output: [7]
print(add_numbers(5, 6)) # Output: [11]
另一種女仰,是開發(fā)設(shè)計的偷懶、或者未進行事先溝通自作主張一罩。
最常見的是更改接口參數(shù)類型差购,返回不符合預(yù)期的結(jié)構(gòu)數(shù)據(jù)。比如不允許為空的字段返回了空稳析,API 版本沒有變化的情況下,增加了必傳的參數(shù)等等
再如陈惰,狀態(tài)碼與實際的情況不符合。
雖然開發(fā)人員處理了幾種已知的錯誤画髓,但是狀態(tài)碼一直是 200,對于調(diào)用方肉微,如果使用 status.OK
則永遠(yuǎn)返回 True
馏艾,處理不到這些異常情況铁孵。
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/delete-file/<file_id>', methods=['DELETE'])
def delete_file(file_id):
try:
# Delete the file
# ...
return jsonify({"status": "success"})
except FileNotFoundError:
return jsonify({"status": "error", "message": "File not found"})
except PermissionError:
return jsonify({"status": "error", "message": "Permission error"})
if __name__ == '__main__':
app.run()
正確的寫法,應(yīng)該使用對應(yīng)的狀態(tài)碼,確保其他框架可以信任這個結(jié)果:
# Following the Principle of Least Astonishment in error handling
from flask import Flask, jsonify
from werkzeug.exceptions import NotFound, Forbidden
app = Flask(__name__)
@app.route('/delete-file/<file_id>', methods=['DELETE'])
def delete_file(file_id):
try:
# Delete the file
# ...
return jsonify({"status": "success"})
except FileNotFoundError:
raise NotFound(description="File not found")
except PermissionError:
raise Forbidden(description="Permission error")
if __name__ == '__main__':
app.run()
Bonus: 有沒有可以抄的解決方法?
- 參考大廠的代碼風(fēng)格規(guī)范
Google 開放了不少常見語言的代碼規(guī)范:
https://google.github.io/styleguide/
小米也有數(shù)據(jù)庫設(shè)計互躬,SQL 相關(guān)的規(guī)范:
https://github.com/XiaoMi/soar
如果接手一個新的語言或工具容为,還可以在搜索資料時加一個 best pratice 看看其他人的經(jīng)驗。
- 借助插件或 CI 工具
對于常見的規(guī)范單行代碼長度、空格等,可以使用 ESLint沮协、Pylint,、 Black (for Python) 等行瑞,直接格式化代碼,或者借助工具查錯
-
多 Review 多溝通
工作中的大部分代碼不是你一個人蠻干,自己的思維局限性副砍,可以通過他人的視角打破。
Ref:
- Syntactic Sugar in Python: https://medium.com/analytics-vidhya/syntactic-sugar-in-python-3e61d1ef2bbf
- 7 simple habits of the top 1% of engineers: https://read.engineerscodex.com/p/7-simple-habits-of-the-top-1-of-engineers