Protocol - Oriented Programming In Swift 2
Bài đăng này đã không được cập nhật trong 9 năm
Trong hội nghị các nhà phát triển của Apple vừa _rồi, Apple đã giới thiệu Swift 2, phiên bản tiếp theo của Swift. Bên cạnh việc đưa Swift 2 trở thành một ngôn ngữ opensource, apple cũng bổ xung rất nhiều tính năng cho ngôn ngữ này.
Ở bài viết này, tôi xin được giới thiệu về một tính năng mới sẽ xuất hiện trong Swift 2 : Protocol extension._
Nếu như trước đây, chúng ta có thể thêm các function vào class, struct và enum. Giờ đây, ta thậm chí có thể thêm chức năng cho cả các protocol có sẵn.
Đầu tiên, chúng ta hãy khởi tạo một playground mới bằng Xcode ( playground là công cụ của Xcode cho phép ta thực thi nhanh các dòng lệnh mà không cần build một project hoàn chỉnh )
Thêm vào những dòng code dưới đây :
protocol Bird {
var name: String { get }
var canFly: Bool { get }
}
protocol Flyable {
var airspeedVelocity: Double { get }
}
Ta đã định nghĩa ra một protocol đơn giản với các thuộc tính : name, canFly. Một protocol Flyable với function : airspeedVelocity.
Trước đây, nếu ta không sử dụng protocol, ta sẽ phải bắt đầu với Flyable như là một class và sau đó kế thừa để định nghĩa ra các class như Bird. Tuy nhiên, giờ đây, ta có thể khiến hệ thống trở nên tuỳ biến hơn với việc sử dụng protocol.
Tạo thêm các Structs FlappyBird
struct FlappyBird: Bird, Flyable {
let name: String
let flappyAmplitude: Double
let flappyFrequency: Double
let canFly = true
var airspeedVelocity: Double {
return 3 * flappyFrequency * flappyAmplitude
}
}
struct Penguin: Bird {
let name: String
let canFly = false
}
struct SwiftBird: Bird, Flyable {
var name: String { return "Swift \(version)" }
let version: Double
let canFly = true
// Swift is FAST!
var airspeedVelocity: Double { return 2000.0 }
}
Với Extenion Protocol, ta có thể định nghĩa thêm cho protocol như sau :
extension Bird where Self: Flyable {
// Flyable birds can fly!
var canFly: Bool { return true }
}
**Tại sao không sử dụng Base Classes? ** _ - Vì ta có thể sử dụng nhiều hơn một protocol
- Protocols có thể được dùng bởi cả classes, struct và enums. Base classes bị giới hạn với class type_
Ví dụ :
enum UnladenSwallow: Bird, Flyable {
case African
case European
case Unknown
var name: String {
switch self {
case .African:
return "African"
case .European:
return "European"
case .Unknown:
return "What do you mean? African or European?"
}
}
var airspeedVelocity: Double {
switch self {
case .African:
return 10.0
case .European:
return 9.9
case .Unknown:
fatalError("You are thrown from the bridge of death!")
}
}
}
Có lẽ, việc thú vị nhất đó là ta có thể thêm vào các hàm mới mẻ cho các protocol có sẵn từ thư viện của Swift.
chẳng hạn như sau :
protocol Bird: BooleanType
extension BooleanType where Self: Bird {
var boolValue: Bool {
return self.canFly
}
}
Tác động tới các thư viện có sẵn của sswift.
Bạn đã thấy protocol extension là một cách rất tuyệt vời để customize và mở rộng các chức năng trong code. Không chỉ vậy, bạn còn có thể ngạc nhiên hơn khi biết được các thư viện của Swift có thể được cải thiện như thế nào.
Chẳng hạn như đối với Aray:
// Counts the number of characters in the array
["frog", "pants"].map { $0.length }.reduce(0) { $0 + $1 } // returns 9
Trong Swift 1.2 :
// Swift 1.2
extension Array : _ArrayType {
/// Return an `Array` containing the results of calling
/// `transform(x)` on each element `x` of `self`
func map<U>(transform: (T) -> U) -> [U]
}```
Trong Swift 2.0:
```Swift
// Swift 2.0
extension CollectionType {
/// Return an `Array` containing the results of mapping `transform`
/// over `self`.
///
/// - Complexity: O(N).
func map<T>(@noescape transform: (Self.Generator.Element) -> T) -> [T]
}
All rights reserved