Hướng dẫn về style và quy ước code trong Swift(Phần 1) - Cách đặt tên, cấu trúc project và tổ chức code..



Một developer phát triển ứng dụng không những code ra những sản phẩm tốt cả về mặt UI,UX mà còn tạo ra những dòng code đẹp, tối ưu và theo một quy ước nhất định(convension code) để về sau dễ bảo trì, nâng cấp code và ứng dụng. Ngoài ra, các developer khác dễ dàng đọc và hiểu code của bạn. Vậy để có những dòng code đẹp, rõ ràng ý nghĩa và xử lý thì chúng ta cần phần tuân thủ một số nguyên tắc trong quá trình code. Sau đây chúng ta sẽ đọc và tìm hiểu một số quy ước, quy tắc code, đặt tên..v..v..Bài viết này rất hữu ích cho các bạn thực hiện điều đó.
Đặc biệt, rất khuyến khích các bạn developer mới tham khảo bài này để thực hành ,rèn luyện việc code thành một thoái quen trong quá trình phát triển ứng dụng của mình và  tạo nên những dòng code tuyệt vời. Chúc các bạn thành công.
  1. Một số nguyên tắc cơ bản
  • Khi đặt tên nên ưu tiên sự rõ ràng hơn sự ngắn gọn và nói lên được ý nghĩa khi sử dụng.
  • Sử dụng cú pháp lạc đà (camel case).
var utf8Bytes: [UTF8.CodeUnit]
var isRepresentableAsASCII = true
var userSMTPServer: SecureSMTPServer
view raw camelCase hosted with ❤ by GitHub
  • Viết hoa chữ cái đầu tiên cho tên của các kiểu dữ liệu tự tạo, class, protocol nhưng lại viết thường chữ cái đầu tiên cho tên hàm, biến.
class MyClass {
}
protocol MyProtocol {
}
func myFunction() {
}
var myVariable: String
view raw sampleName hosted with ❤ by GitHub
  • Sử dụng các từ ngữ tránh gây nhầm lẫn, có ý nghĩa mơ hồ cho người đọc code tại nơi sử dụng.
Khuyên dùng:
extension List {
public mutating func remove(at position: Index) -> Element
}
employees.remove(at: x)
view raw sampleUseWord hosted with ❤ by GitHub
Không nên dùng:
extension List {
public mutating func remove(position: Index) -> Element
}
employees.remove(x)
view raw sampleUseWord_1 hosted with ❤ by GitHub

Nếu bỏ từ at đi khi sử dụng hàm remove, người dùng sẽ không biết hàm đó remove như thế nào.
  • Tránh sử dụng các từ viết tắt không thông dụng, nếu bạn dùng từ viết tắt thì hãy ghi bằng chữ IN HOA.
productURL = NSURL()
userID = "12345"
view raw sampleName_1 hosted with ❤ by GitHub
  • Bỏ qua những từ không cần thiết.
Khuyên dùng:
public mutating func remove(_ member: Element) -> Element?
allViews.remove(cancelButton) // rõ ràng
view raw sampleClear hosted with ❤ by GitHub
Không nên dùng:
public mutating func removeElement(_ member: Element) -> Element?
allViews.removeElement(cancelButton)
view raw sampleClear_1 hosted with ❤ by GitHub
Từ Element không cần thiết, do mình đã biết cancelButton là một element trong View rồi nên chỉ cần remove cancelButton là đủ hiểu hàm đó làm gì rồi.
  • Nếu dùng từ viết tắt thì phải thống nhất từ trên xuống dưới và trong toàn bộ project.
  • Đặt tên cho các tham số của hàm nên có mối liên hệ với nhau và nói lên được xử lý của hàm đó.
Khuyên dùng:
func addObserver(_ observer: NSObject, forKeyPath path: String)
grid.addObserver(self, forKeyPath: graphics) // rõ ràng
view raw toNameSample hosted with ❤ by GitHub
Không nên dùng:
func add(_ observer: NSObject, for keyPath: String)
grid.add(self, for: graphics) // Khá mơ hồ khi sử dụng
view raw toNameFaile hosted with ❤ by GitHub
  • Nên viết comment để mô tả ngắn gọn ý nghĩa của một hàm hoặc một biến nào đó. Apple hỗ trợ cho chúng ta rất nhiều markup để comment code, để tìm hiểu kỹ hơn bạn tham khảo tại đây.
Ví dụ:
/// A collection that supports equally efficient insertion/removal
/// at any position.
struct List {
/// The element at the beginning of `self`, or `nil` if self is
/// empty.
var first: Element? …
}
view raw commentSample hosted with ❤ by GitHub
    1. Delegates
Khi tạo một hàm delegate nào đó, tên hàm nên ẩn đi tham số đầu tiên bằng ký tự _. Như ví dụ bên dưới.
Khuyến khích dùng:
func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)
func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool
view raw sampleFuncName hosted with ❤ by GitHub

Không nên dùng:
func didSelectName(namePicker: NamePickerViewController, name: String)
func namePickerShouldReload() -> Bool

    1. Kiểu tự suy luận(Inferred type)
Khuyến khích dùng:
let selector = #selector(viewDidLoad)
view.backgroundColor = .red
let toView = context.view(forKey: .to)
let view = UIView(frame: .zero)
view raw inherredSamle_1 hosted with ❤ by GitHub

Không nên dùng:
let selector = #selector(ViewController.viewDidLoad)
view.backgroundColor = UIColor.red
let toView = context.view(forKey: UITransitionContextViewKey.to)
let view = UIView(frame: CGRect.zero)

    1. Ngôn ngữ
khuyên các bạn nên dùng ngôn ngữ tiếng anh để đặt tên hàm và biến, cũng như các tên khác. cụ thể hơn nên dùng US English.

Khuyến khích dùng:
let color = "red"
Không nên dùng:
let colour = "red"


  1. Cấu trúc một project
Hãy để tất cả các source nguồn, code của bạn chung trong một thư mục nào đó. Và bạn có thể thiết lập cấu trúc thư mục trong project của bạn tuỳ theo từng project, nhưng khuyến khích bạn nên đặt tên và sắp xếp cấu trúc thư mục để dễ dàng tìm kiếm các file trong thư mục.
Ví dụ như:

├─ Models
├─ Views
├─ Controllers (or ViewModels, if your architecture is MVVM)
├─ Stores
├─ Helpers
Models là thư mục chứa các class modules.
Views là thư mục chứa các view, các custom view, các file .xib liên quan.
Controllers là thư mục chứa các UIViewcontroller các file .xib liên quan.
Stores là thư mục chưa các file database, các xử lý lưu trữ.
Helpers là nơi chứa các file hỗ trợ trong code của bạn như các lớp extension, các lớp hỗ trợ request api, các hàm hỗ trợ trong quá trình xử lý của mình, ..v.v..


Ví dụ:




  1. Tổ chức code trong một file
Khi sử dụng extension trong class hay struct, bạn nên dùng cú pháp: “ // MARK: - “
để comment code, giúp cho việc hiểu ý nghĩa và đọc code về sau dễ dàng hơn.
Khuyên dùng:
class MyViewController: UIViewController {
// class stuff here
}
// MARK: - UITableViewDataSource
extension MyViewController: UITableViewDataSource {
// table view data source methods
}
// MARK: - UIScrollViewDelegate
extension MyViewController: UIScrollViewDelegate {
// scroll view delegate methods
}
view raw gistfile1.txt hosted with ❤ by GitHub


Không nên dùng:
class MyViewController: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
// all methods
}
Lưu ý:
Khi đã import UIKit thì không nên import Foundation vì trong UIKit đã có import Foundation rồi.
Bạn không nên định nghĩa nhiều public, internal cho class,struct, enum trong cùng một file. Nên định nghĩa chúng ở mỗi file khác nhau để dễ quản lý và tìm kiếm.
Gợi ý tổ chức code chung cho một file .Swift, sắp xếp theo thứ tự như sau:
Trước tiên sẽ mô tả:
  • Private  Class/Struct/Enum
Sau đó mô tả bên trong sẽ là:
  • Override Properties
  • Properties
  • Static/Class Variables
  • Static/Class Functions
  • Init/Deinit
  • Override Functions
  • Instance Functions
Cuối file nên mô tả:
  • Extensions
Mỗi phần ở trên sử dụng từ khoá truy cập được sắp xếp như sau:
  • Open
  • Public
  • Internal
  • Fileprivate
  • Private
Ngoài ra để tổ chức source trong 1 file trở nên chuyện nghiệp thì khuyên các bạn dụng:
//MARK:  thường dùng để comment khi dùng các extension.
Ví dụ:
// MARK: UITableViewDelegate Functions
Bạn có thể dùng TODO, FIXME để tạo các ghi chú trong file của bạn, khi đó truy xuất tới nó sẽ dễ hơn.
Ví dụ:
// TODO: implement this feature
// FIXME: fix it it's not working


Thông qua các nguyên tắc cơ bản, cấu trúc project và file ở trên, chắc các bạn cũng nắm được tổng quát các cách để code ra những dòng code đẹp và project theo một chuẩn chung trong quá trình phát triển ứng dụng iOS của bản thân.
Phần tiếp theo chúng ta sẽ đi tìm hiểu chi tiết hơn và tập trung vào style,convention code trong class, struct, closure, method… để góp phần nâng cao và hoàn thiện kỹ năng code của bạn khi phát triển ứng dụng iOS.
Hy vọng các bạn thích và học được nhiều kiến thức từ bài viết này. Mong các bạn chia sẽ nó để mọi người cùng học và cùng trao đổi. Mọi thắc mắc hay trao đổi về bài viết, các bạn có thể để lại bình luận bên dưới mình sẽ hỗ trợ sớm nhất.

Post a Comment

0 Comments