Tùy biến model trong Swift

Tram Ho

  • Là lập trình viên, chúng ta thường làm việc trên các ứng dụng và hệ thống bao gồm nhiều thành phần được kết nối nhiều cách khác nhau. Đặc biệt là khi sử dụng ngôn ngữ lập trình có tính chặt chẽ cao như Swift thì khó tìm ra cách model phần data vừa thỏa mãn trình biên dịch vừa có codebase dễ đọc.

  • Chúng ta hãy xem xét một trường hợp bao gồm việc mô hình hóa nhiều tùy chỉnh của cùng một model data và vài kỹ thuật , phương pháp khác nhau cho phép chúng ta xử lý data một cách an toàn.

1/ Mixed structures:

  • Giả sử rằng chúng ta đang làm việc trên một ứng dụng nấu ăn bao gồm cả video và công thức nấu ăn dưới dạng văn bản và content chúng ta được trả về từ web service dưới dạng JSON như sau:

  • Cấu trúc JSON như bên trên là cực kỳ phổ biến nhưng việc tạo các struct phù hợp với nó có thể khá khó khăn. Chúng ta nhận được một array các item gồm công thức nấu ăn và video. Chúng ta sẽ cần viết model mà chúng ta có thể decode đồng thời cả hai tùy chỉnh đó.

  • Một cách để làm điều đó là tạo ra một enum ItemType bao gồm các trường hợp cho hai tùy chỉnh của chúng ta cũng như một model data hợp nhất có chứa tất cả các thuộc tính mà chúng ta gặp phải và đóng gói ItemCollection:

  • Cách tiếp cận trên cho phép chúng ta decode JSON nhưng nó vẫn chưa tối ưu vì chúng ta buộc phải triển khai phần lớn các thuộc tính dưới dạng tùy chỉnh chẳng hạn như VideoPlayer này:

2/ Complete polymorphism:

  • Chúng ta cố gắng model data một tập hợp dữ liệu thành nhiều kiểu khác nhau. Chúng ta có thể tạo một protocol Item chứa tất cả các thuộc tính được chia sẻ giữa hai biến thể cũng như hai type riêng biệt:

  • Chúng ta cũng muốn sửa đổi trình bao bọc ItemCollection của chúng ta để bao gồm các array riêng cho từng type trong hai type vì nếu không làm thế chúng ta sẽ phải liên tục nhập các giá trị cho Video hoặc Recipe :

  • Để có thể sử dụng lại các implement ItemItemCollection từ trước đồng thời đổi tên chúng để phù hợp với mục đích mới :

  • Chúng ta đã sẵn sàng để Decodable nhưng vì chúng ta sẽ cần phải thêm một vài tùy chọn khi thực hiện điều đó:

  • Bây giờ hãy viết decode thực tế. Chúng ta sẽ bắt đầu bằng cách decode một phiên bản của . Chúng ta sẽ chuyển đổi các mục của ItemCollection thành VideoRecipe như sau:

  • Thay vì coi các instance là các cách triển khai khai riêng biệt có protocol hãy coi chúng là các instance của cùng một model. Điều đó sẽ có tác động khá lớn đến công đoạn cuối của chúng ta cấu trúc mô hình.

  • Hãy đổi tên protocol Item trước đó thành ItemVariant và bỏ thuộc tính type của nó:

  • Chúng ta mô hình hóa loại item thực tế của chúng ta dưới dạng enum như sau:

  • Chúng ta có thể đơn giản hóa rất nhiều việc triển khai decode diễn ra hoàn toàn trong chính loại Item mới và chỉ cần kiểm tra từng giá trị loại của mục JSONđể quyết định loại decode nào:

  • Do việc triển khai Item của chúng ta chịu trách nhiệm decode các instance của chính nó và giờ chúng ta có thể ItemCollection được trả lại trở lại đơn giản là array các giá trị Item cho phép dựa vào triển khai mặc định của Decodable:

  • Lợi ích là c chúng ta tiếp tục sử dụng các mô hình chuyên dụng đồng thời giữ cho decode của chúng ta đơn giản và thứ tự item tổng thể được giữ nguyên nhưng đi kèm với nhược điểm là yêu cầu giải nén từng item trước khi sử dụng:

  • Mặc dù chúng ta sẽ phải tiếp tục viết code như trên bất cứ khi nào chúng ta cần truy cập data cụ thể cho công thức nấu ăn hoặc Video. Chúng ta có thể làm để cung cấp quyền truy cập trực tiếp vào bất kỳ thuộc tính được xác định trong protocol ItemVariant và sử dụng tính năng tra cứu subscription của Swift.

  • Việc thêm thuộc tính @dynamicMemberLookup vào khai báo item chính của chúng ta:

  • Từ Swift 5.1 chúng ta có thêm cách hỗ trợ cho các subscription theo cách hoàn toàn an toàn và dễ dàng như sau:

  • Bây giờ chúng ta có thể truy cập bất kỳ thuộc tính nào được chia sẻ giữa VideoRecipe (thông qua protocol ItemVariant) như thể thuộc tính đó được xác định trong chính loại Item . Chúng ta có thể chuyển đổi phương thức allTitle thành như sau :

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo