12/08/2018, 16:26

Delegate pattern trong Swift.

Một trong những thử thách mà đa số học sinh gặp phải trong quá trình học lập trình iOS đó là Delegate parttern và bản thân tôi cũng không biết tại sao lại như vậy? Chúng ta đều biết Delegate pattern rất mạnh mẽ nhưng lại thường không biết lúc nào nên sử dụng và đặt chúng vào đâu trong quá trình ...

  • Một trong những thử thách mà đa số học sinh gặp phải trong quá trình học lập trình iOS đó là Delegate parttern và bản thân tôi cũng không biết tại sao lại như vậy? Chúng ta đều biết Delegate pattern rất mạnh mẽ nhưng lại thường không biết lúc nào nên sử dụng và đặt chúng vào đâu trong quá trình học tập. Để giải quyết vấn đề này chúng ta sẽ hướng đến những vấn đề thật trong đời sống và hướng chúng đến những kiểu mẫu có sẵn trong lập trình:
    • Tưởng tượng một người(Person) làm mất chìa khóa nhà và đánh một chiếc chìa khóa mới.
    • Người đó không quan tâm cách làm chìa khóa(Key) , mất bao lâu , dùng công cụ để hoàn thành chiếc chìa khóa v.v...
    • Điều duy nhất người đó cần biết là hình dạng chiếc chìa khóa ra sao và ai có thể làm chiếc chìa khóa đó.
    • Người đó đi tìm thợ khóa(Keymaker) để làm chiếc chìa khóa đó.
    • Người đó đi đến cửa hàng khóa và làm một số thủ tục sau:
      • Đăng ký thông tin liên lạc để thợ khóa liên lạc khi làm khóa xong.
      • Cho biết phương pháp bạn nhận được chìa khóa từ thợ khóa.
      • Việc còn lại là chờ đợi cuộc gọi và nhận chìa khóa.
    • Thợ khóa sẽ làm khóa trong thời gian đó(KeyMaking) và khi làm xong:
      • Thợ khóa sẽ tìm liên lạc của khách hàng
      • Gọi điện và giao chìa khóa.

Vấn đề trên rất gần với Delegate pattern và sau đây hãy triển khai nó trong Swift:

  • Đầu tiên chúng ta cần tạo data model cho Key với đặc tiểm hình dạng cần có:
struct Key {
   var shape: String
}
  • Tiếp đến chung ta cần model là Person, đối tượng người mất chìa khóa để thực hiện công việc đi đặt thợ làm khóa.
final class Person {
    var name: String = "Me"
    var key: Key?
}
  • Cuối cùng hãy để thợ làm khóa thực hiện việc làm khóa cho bạn:
final class Keymaker {
    weak var customer: Keymaking?
}
  • Có 2 điều cần chú ý ở đây:
  1. customer chỉ là là 1 object ám chỉ Keymaker chỉ làm việc với 1 customer tại thời điểm đó. Công việc của developer là nếu 1 object được khai báo là customer thì không có object nào được khai báo với customer trong thời gian đó, bằng không thì customer sẽ không nhận được chìa khóa.
  2. Keymaker chỉ quan tâm những gì customer đã đặt hàng và thực thi chúng. Những điều kiện mà customer đặt hàng trong Swift ta gọi là protocol.

Protocol là những điều kiện trong giao hẹn của customer mà Keymaker bắt buộc phải tuân theo:

protocol Keymaking: class {
    func keymaker(_ keymaker: Keymaker, didProduceKey key: Key)
}
  • Điều lưu ý ở đây customer là 1 phần hợp đồng Keymaking, dịch vụ hợp đồng bao gồm việc Keymaker làm khóa cho bất kì ai chỉ cần người đó tuân thủ với cách làm khóa và giao khóa của Keymaker.
extension Person: Keymaking {
    func keymaker(_ keymaker, didProduce key: key) {
    self.key = key
    }
}
  • Khi Keymaker làm xong khóa sẽ liên lạc và giao hàng theo phương thức trong hợp đồng:
fileprivate extension Keymaker {
    func didProduceKey(_ key: Key) {
        customer?.keymaker(self, didProduceKey: key)
    }
}
  • Vì cách sử dụng khóa là của riêng customer nên ta sẽ để ở đây là fileprivate.
  • Delegate pattern là một pattern được sử dụng trong khắp các ứng dụng iOS cho nên việc hiểu và vận dụng nó là một vấn đề sống còn trong việc lập trình iOS của Developer.
  • Bạn sẽ gặp nó với UITextField - UITextFieldDelegate/ UITableView-UITableViewDataSource-UITableViewDelegate.
  • Với tóm tắt trên hi vọng bạn sẽ hiểu và cảm thấy thoải mái khi dùng Delegate Pattern. Bài viết đầu có nhiều thiếu sót, mong mọi người giúp đỡ.
0