Protocol-oriented programming - Phần 1 - Protocol cơ bản

1. Giới thiệu chung

Swift là một dạng languague protocol-oriented programming (POP). POP không chỉ liên quan đến mỗi protocol mà còn mang nhiều ý nghĩa khác.

Với POP, ta phải thay đổi cả cách viết app cũng như thay đổi cách tiếp cận khi code.

POP không đơn giản chỉ là đổi cái tên từ OOP sang POP (vì Protocol ban đầu nghe có vẻ giống Interface trong OOP).

Loạt bài này, sẽ xem sự giống và khác nhau, ưu nhược điểm của chúng? 

Những điểm chính sẽ tập trung:

  • Cách define property and functional requirements bên trong 1 protocol 
  • Kế thừa và đóng gói
  • Sử dụng protocol như 1 type
  • Đa hình
  • Sử dụng associated types
  • Delegation pattern với protocols
  • Type requirements với protocols

2. Những quy tắc cơ bản

a. Tổng quan                                   

Thay vì bắt đầu với hệ thống phân cấp lớp, với POP ta nên bắt đầu với protocol. Nó gần như là xương sống của 1 dự án dùng POP. 

Trong POP,  bất cứ type nào conforms 1 protocol nào đó phải chắc chắn implement tất cả những yêu cầu mà được định nghĩa bởi protocol đó. Nếu không thì ta sẽ bị compile-time error. 

Class, Structure, or Enumeration đều có thể conform 1 protocol.

Hiện giờ, Swift và các thư viện chuẩn của nó đều đã thực hiện POP. Do đó việc hiểu rõ và áp dụng vào app là điều gần như phải làm.

b. Syntax

b.1 Khai báo property

CẦNKHÔNG CẦN
- read-only or a read-write
- chỉ rõ type của property's type vì ta không thể dùng type inference trong một protocol
- có thể khai báo static.
The protocol KHÔNG CẦN KHAI BÁO NÓ LÀ stored or computed. Vì việc khai báo chi tiết để cho phần implementation.


Ví dụ:                                         

protocol FullName {     
   var firstName: String {get set}     
   var lastName: String {get set}
   static var typeProperty: String {get}
}

{get set} -> read & write

{get} -> read only

{set} -> write only


b.1 Khai báo function

CẦNKHÔNG CẦN
- Khai báo tên hàm và return value
- Có thể khai báo static
- { } và body bên trong.
- giá trị default của argument.


- Đối với việc sử dụng hàm để thay đổi instance cho Struct và Enum, ta dùng mutating keywordKhông áp dụng cái này cho class.

protocol FullName {     
   var firstName: String {get set}     
   var lastName: String {get set}
   static var typeProperty: String {get}
   func getName() -> String
   mutating func updateFirstName() 
}


c. Khai báo Optionals

Khi mà ta cần khai báo property hoặc func mà không bắt buộc implement. Ta dùng @objc optional trước các giá trị đó

                                                
@objc protocol Phone {     
  var phoneNumber: String {get set}     
  @objc optional var emailAddress: String {get set}     
  func dialNumber()      
  @objc optional func getEmail()
}

3. Protocol inheritance

- Giống như kế thừa trong class, protocol cũng có thể kế thừa được. 

- Không giới hạn số protocol kế thừa

protocol A {}
protocol B {}
protocol C: A, B {}

Bất cứ type nào muốn conform thì chỉ cần conform C là đủ và không cần A,B nhưng nó phải implement các requirements từ A, B, C.

4. Protocol composition

Xem ví dụ sau:

class Athletic { var name }
class Pro: Athletic { var paid }
class Amateur: Athletic { var collegue }

Bây giờ ta muốn có ProFootballer, AmateurFootballer, AmateurBasketball, ProBasketball thì

class ProFootballer: Pro { var run }
class AmateurFootballer: Amateur { var run }
class ProBasketball: Pro { var shoot }
class AmateurBasketball: Amateur { var shoot }

Đã xuất hiện code duplicate. Nếu dùng protocol, ta có thể tách ra thành nhiều phần khác nhau. Lưu ý check cẩn thận nếu không sẽ có nhiều protocol mà chỉ có 1 vài property sẽ rất phí.

Bình luận
* Các email sẽ không được công bố trên trang web.
I BUILT MY SITE FOR FREE USING