POP – Protocol-Oriented Programming trong Swift
POP là gì và vì sao Swift “ưu ái”?
Protocol-Oriented Programming là phong cách thiết kế trong đó bạn mô hình hoá hành vi bằng protocol, sau đó “ghép” hành vi cho kiểu dữ liệu (struct/class/enum) bằng cách conform (tuân thủ protocol) và protocol extension.
Swift khuyến khích POP vì:
-
Composition > Inheritance: thay vì kế thừa sâu (class inheritance), ta lắp ghép hành vi linh hoạt.
-
Làm việc tốt với struct/value semantics (an toàn hơn, ít side effect).
-
Protocol extension cho phép cung cấp “mặc định” (default implementation) và viết code tái sử dụng gọn gàng.

Nguồn: https://www.swiftanytime.com/blog/protocol-oriented-programming-in-swift
1) Protocol cơ bản
Giả sử ta muốn mọi đối tượng “có thể mô tả”:
protocol Describable {
var descriptionText: String { get }
}
Bất kỳ type nào conform đều phải cung cấp descriptionText.
2) Default implementation với Protocol Extension
Thế mạnh của POP nằm ở đây: bạn có thể viết hành vi dùng chung mà không cần base class.
protocol Loggable {
var tag: String { get }
func log(_ message: String)
}
extension Loggable {
func log(_ message: String) {
print("[\(tag)] \(message)")
}
}
Giờ chỉ cần conform Loggable là có log() sẵn.
struct NetworkService: Loggable {
let tag = "NETWORK"
}
let api = NetworkService()
api.log("Request started")
3) “Lắp ghép” hành vi bằng nhiều protocol
Thay vì tạo class kế thừa chồng chéo, ta chia nhỏ hành vi:
protocol IdentifiableEntity {
var id: String { get }
}
protocol Timestamped {
var createdAt: Date { get }
}
protocol Cacheable {
func cacheKey() -> String
}
extension Cacheable where Self: IdentifiableEntity {
func cacheKey() -> String { "cache:\(id)" }
}
Type nào vừa Cacheable vừa IdentifiableEntity sẽ tự có cacheKey().
struct User: IdentifiableEntity, Timestamped, Cacheable {
let id: String
let createdAt: Date
}
let u = User(id: "u_123", createdAt: .now)
print(u.cacheKey()) // cache:u_123
Điểm hay: cacheKey() chỉ khả dụng khi thỏa điều kiện where Self: IdentifiableEntity.
4) Protocol + Associatedtype (generic hoá hành vi)
Khi cần “hành vi chung nhưng dữ liệu khác nhau”, associatedtype rất mạnh:
protocol Repository {
associatedtype Entity
func get(by id: String) -> Entity?
}
Triển khai cụ thể:
struct UserRepository: Repository {
typealias Entity = User
private var storage: [String: User] = [:]
func get(by id: String) -> User? {
storage[id]
}
}
Lưu ý: Protocol có associatedtype thường khó dùng trực tiếp như một type (existential) nếu không dùng any/type erasure. Đây là một trade-off cần nắm.
5) Static Dispatch vs Dynamic Dispatch (một “bẫy” thường gặp)
Default implementation trong extension có thể dẫn tới hành vi khác nhau tuỳ cách bạn gọi.
Ví dụ:
protocol Greeter {
func greet()
}
extension Greeter {
func greet() { print("Hello from extension") }
}
struct Person: Greeter {
func greet() { print("Hello from Person") }
}
let p = Person()
p.greet() // Hello from Person
let g: Greeter = Person()
g.greet() // thường vẫn gọi implementation theo witness table (greet của Person)
Nhưng với method chỉ tồn tại trong extension (không khai báo trong protocol), khi gọi qua biến kiểu protocol có thể không thấy/không dispatch như bạn kỳ vọng. Thực hành tốt: những API bạn muốn “hợp đồng hoá” nên khai báo trong protocol, extension chỉ để default.
6) Khi nào nên dùng POP?
Phù hợp khi:
-
Bạn muốn tách nhỏ hành vi thành các “mảnh” ghép.
-
Bạn ưu tiên struct/value type và muốn tái sử dụng code.
-
Bạn muốn API rõ ràng theo capability (“có thể log”, “có id”, “có thể cache”…).
Không nên lạm dụng khi:
-
Bạn cần shared mutable state phức tạp (class đôi khi phù hợp hơn).
-
Bạn gặp quá nhiều vấn đề về type erasure/associatedtype, làm API khó dùng.
-
Hệ thống cần runtime polymorphism mạnh và phức tạp (một số trường hợp OOP/class vẫn hợp lý).
Kết luận
POP trong Swift là cách thiết kế tập trung vào protocol + extension + composition để tạo hệ thống linh hoạt, dễ test, ít phụ thuộc, và tận dụng tốt struct/value semantics. Chìa khoá là: định nghĩa “hợp đồng” bằng protocol, cung cấp default bằng extension, và ghép nhiều protocol để mô hình hoá tính năng.
Tham khảo hình ảnh: https://codetoanbug.com/protocol-oriented-programming-trai-tim-cua-swift/
- Performance Testing – P4
- Chứng Chỉ Quỹ: "Hack Game" Tài Chính Cho Sinh Viên Thời 4.0
- Computer Vision: Công Nghệ Thị Giác Máy Tính – Từ Nền Tảng Đến Tương Lai
- Hợp nhất Báo cáo Tài chính (Consolidated Financial Statements)
- [THÔNG BÁO] – Lịch bảo về Đồ án Capstone và một số nội dung quan trọng (Đợt tháng 12/2025)