Một số lưu ý khi đặt tên hàm tên biến theo chuẩn của apple
Việc đặt tên hàm, tên biến cho chuẩn mực là hết sức quan trọng trong quá trình bảo trì một sản phẩm. Kinh nghiệm, trình độ của một lập trình viên phần nào thể hiện qua cách đặt tên hàm tên biến. Vậy làm thế nào để đặt tên hàm, tên biến cho chuẩn mực? Chúng ta hãy cùng tìm hiểu xem, người thầy của ...
Việc đặt tên hàm, tên biến cho chuẩn mực là hết sức quan trọng trong quá trình bảo trì một sản phẩm. Kinh nghiệm, trình độ của một lập trình viên phần nào thể hiện qua cách đặt tên hàm tên biến. Vậy làm thế nào để đặt tên hàm, tên biến cho chuẩn mực?
Chúng ta hãy cùng tìm hiểu xem, người thầy của chúng ta Apple, khuyến khích chúng ta làm thế nào?
Nguyên lý đặt tên
- Rõ ràng ở thời điểm sử dụng là mục tiêu quan trọng.
- Rõ ràng thì quan trọng hơn ngắn gọn
- Viết documentation comment ở mỗi khai báo.
Đặt tên
Đặt tên phải có đủ tất cả những từ cần
employees.remove(x) // Prefer employees.remove(at: x)
Với cách dùng đầu thì chúng ta sẽ không hiểu remove cái gì từ employees? x là số thứ tự hay x là employee??
Cách thứ 2 đã xử lý tốt hơn cho chúng ta thông tin rõ ràng là chúng ta remove tại vị trí x
Loại bỏ những từ không cần
books.removeElement(book1) // Prefer books.remove(book1)
Trong các books, remove thì chắc chắn là phải remove book rồi nên vì vậy chữ element ở đây là không cần thiết.
Đặt tên biến, tham số, và các loại có liên quan dựa vào vai trò hơn là loại của nó
var string = "Hello" var greeting = "Hello" // Prefer var containerView: UIView var leftMenu: UIView
Việc đặt tên biến theo loại của nó không phải là không tốt. Nó giúp cho chúng ta nhìn và hiểu được ngay loại của nó. Nếu đặt được tên vừa thể hiện vai trò của nó, vừa thể hiện loại của nó thì rất tốt. Nhưng nếu phải lựa chọn, giữa đặt tên theo vai trò, hay đặt tên theo loại thì đặt tên theo vai trò của nó quan trọng hơn việc đặt tên theo loại.
Bổ xung thêm thông tin để làm rõ chức năng nhiệm vụ
func add(_ observer: NSObject, for keyPath: String) grid.add(self, for: graphics) // Prefer func addObserver(_ observer: NSObject, forKeyPath path: String) grid.addObserver(self, forKeyPath: graphics)
Trường hợp đầu nó gọn hơn đấy chứ? Nhưng mà nó gọn quá nên khi sử dụng API, người ta không thể hiểu nổi
- Add cái gì cho grid
- add cho graphics là cái gì?
Trong trường hợp này, chắc phải thánh mới hiểu ý của người viết code. Và trong mọi trường hợp, ngắn gọn xúc tích cũng khá quan trọng nhưng chúng ta cần sự rõ nghĩa hơn.
trong cách thiết kế API thứ 2, chúng ta đã hiểu được chúng ta add cái gì cho grid - addObserver. Và add cái đấy cho cái key nào: forKeyPath
Phấn đầu sử dụng thành thạo các quy luật sau
Đặt tên Method, Function đúng ngữ pháp tiếng anh
x.insert(y, position: index) x.subViews(color: y) // Prefer x.insert(y, at: index) // x insert y at index x.subViews(havingColor: y) // x's subviews having color y
Factory Method nên bắt đầu với bằng "make"
let iphone = AppleStore.makeIphone(serial: "7 Plus")
Functon và Method nên được đặt theo hướng tác dụng của nó
Với các hoạt động mà thường được biểu diễn bằng động từ
Để biểu đạt cho hướng tác dụng về phía bản thân đối tượng gọi hàm người ta dùng động từ.
list.sort() // sort list list.append(y) // append y to list
ở đây sort và append là cho list, ảnh hưởng đến List. Vì vậy sort và append là động từ. Chúng ta có thể hiểu trong trường hợp này là: - xắp xếp thứ tự của danh sách. - Thêm y vào cuối danh sách.
Để biểu đạt việc, đối tượng gọi hàm không thay đổi, nhưng giá trị trả về của nó thay đổi thì người ta thường dùng phân từ II hoặc động từ tiếp diễn của động từ.
let z = list.sorted() // z equal to list is sorted let z = list.appending(y) // z equal to list appending (y)
trong trường hợp này chúng ta có thể hiểu:
- z bằng danh sách list đã được sắp xếp
- z bằng danh sách cái mà đã được thêm y
Với các hoạt động thường được diễn đạt bởi danh từ
let x = y.union(z)
Ở đây chúng ta hiểu rằng x là tập hợp của y với z
y.fromUnion(z)
Ở đây chúng ta hiểu là tập y được lấy từ việc hợp của chính nó với z. Tập y ở đây bị thay đổi.
Tên của các biến Bool hoặc Method trả về Bool nên được đặt sao cho người đọc code có thể dễ dàng khi quyết định sử dụng
books.isEmpty line1.intersects(line2) string.contents(subString)
- Trong trường hợp books rỗng thì người ta sẽ làm gì đó
- Trong trường hợp line1 giao line2 thì người ta sẽ làm gì đó..
- Trong trường hợp chuỗi string có chưa một chuỗi con thì người ta sẽ làm gì đó.
Việc đặt tên biến Bool cần phải dễ hiểu để người dùng có thể quyết định rõ ràng khi sử dụng
Đặt tên của Protocol
Nếu protocol miêu tả một cái gì đó thì nên đặt tên là danh từ VD: Collection
Nhưng nếu protocol miêu tả về khả năng thì chúng ta đặt tên là một tính từ hoặc danh động từ VD: Equalable, ProgressReporting, LifeCycleReporting,
Function có thể vắng mặt các Argument Labels trong một số trường hợp
-
Các tham số có vai trò tương đương nhau không thể phân biệt
min(x, y, z)
-
Các function thì chung và không có ràng buộc
print(x)
-
Cú pháp của function góp phần tạo nên một công thức mà nhiều người biết
sin(x)
-
Chuyển đổi giữa các loại với nhau thì cũng không cần Argument Labels
Int64(someUInt32)
Cách đặt tên cho các Parameter
Theo tên được viết trong Documentation Chọn những cái tên để viết Documentation sao cho dễ đọc.
/// Replace the given `subRange` of elements with `newElements` mutating func replaceRange(_ subRange: Range, with newElements: [E])
Khai thác tối đa các giá trị defaulted parameters để làm cho hàm dễ sử dụng hơn
let order = lastName.compare(royalFamilyName, options: [], range: nil, locale: nil) // Prefer let order = lastName.compare(royalFamilyName)
Để viết được cách ở dưới thì cần phải viết hàm như sau
public func compare(_ other: String, options: CompareOptions = [], range: Range? = nil, locale: Locale? = nil) -> Ordering
Không đặt cụm giới từ ở Agrument Label đầu tiên. Hãy chuyển nó sang tên hàm
a.move(toX: b, y:c) //Prefer a.moveTo(x: b, y: c)
Nếu first Agrument Label không phải là một phần trong một câu có ngữ pháp thì nhất định không được bỏ qua First Agrument Label
view.dismiss(false) // prefer view.dismiss(animated: false)
trong cách thứ 1 thì dismiss cái gì false, không dismiss nữa à? Cách thứ 2 đã giải quyết được sự mơ hồ về mặt nội dung khi cho têm label animated vào