Cách chọn Kiến trúc iOS phù hợp (Phần 2)

MVC, MVP, MVVM, VIPER hoặc VIP

Bạn có thể tham khảo phần một ở đây.

Kiến trúc chính của iOS

Một tổng quan ngắn gọn.

MVC

Các lớp MVC như sau:

M: Logic nghiệp vụ, lớp mạng và lớp truy cập dữ liệu

V: Lớp UI (Thứ UIKit, Bảng phân cảnh, Xibs)

C: Phối hợp hòa giải giữa Model và View.

Để hiểu MVC chúng ta phải hiểu bối cảnh mà nó được phát minh ra. MVC được phát minh trong những ngày phát triển Web cũ, nơi Views không có trạng thái. Vào thời xưa, mỗi lần chúng ta cần một sự thay đổi trực quan trên trang web, trình duyệt lại tải lại toàn bộ HTML. Tại thời điểm đó không có khái niệm về trạng thái xem được duy trì và lưu.

Ví dụ, có một số nhà phát triển đã trộn lẫn trong cùng một tệp HTML, PHP và quyền truy cập cơ sở dữ liệu. Vì vậy, động lực chính của MVC là tách lớp View khỏi lớp Model. Điều này làm tăng khả năng kiểm tra của lớp Model. Giả sử trong MVC, lớp View và Model sẽ không biết gì về nhau. Để thực hiện điều này là có thể, một lớp trung gian có tên là Bộ điều khiển đã được phát minh. Đây là SRP đã được áp dụng.

Một ví dụ về chu trình MVC:

  1. Một hành động / sự kiện của người dùng trong Lớp xem (ví dụ: Làm mới hành động) được kích hoạt và hành động đó được truyền đến Bộ điều khiển
  2. Bộ điều khiển hỏi dữ liệu cho Lớp mẫu
  3. Mô hình hóa dữ liệu trả về Bộ điều khiển
  4. Trình điều khiển cho biết Chế độ xem cập nhật trạng thái của mình với Dữ liệu mới
  5. Xem cập nhật trạng thái của mình

Apple MVC

Trong iOS, Trình điều khiển xem được ghép nối với UIKit và chế độ xem vòng đời, do đó, nó không phải là MVC thuần túy. Tuy nhiên, trong định nghĩa MVC, không có gì để nói rằng Bộ điều khiển có thể hiểu biết về triển khai cụ thể của Chế độ xem hoặc Mô hình. Mục đích chính của anh ta là tách các trách nhiệm của lớp Model khỏi lớp View để chúng ta có thể sử dụng lại nó và kiểm tra lớp Model một cách riêng biệt.

ViewContoder chứa View và sở hữu Model. Vấn đề là chúng ta đã sử dụng để viết mã điều khiển cũng như mã xem trong ViewContoder.

MVC thường tạo ra vấn đề được gọi là Massive View Controller, nhưng điều đó chỉ xảy ra và trở thành một vấn đề nghiêm trọng trong các ứng dụng có đủ độ phức tạp.

Có một số phương pháp mà nhà phát triển có thể sử dụng để làm cho Trình điều khiển xem dễ quản lý hơn. Vài ví dụ:

  • Trích xuất logic VC cho các lớp khác như bảng xem phương thức nguồn dữ liệu và ủy quyền cho các tệp khác bằng cách sử dụng mẫu thiết kế ủy nhiệm.
  • Tạo sự phân tách trách nhiệm khác biệt hơn với thành phần (ví dụ: Tách VC thành các bộ điều khiển xem con).
  • Sử dụng mẫu thiết kế điều phối viên để loại bỏ trách nhiệm triển khai logic điều hướng trong VC
  • Sử dụng lớp trình bao bọc DataPresenter đóng gói logic và biến mô hình dữ liệu thành đầu ra dữ liệu biểu thị dữ liệu được trình bày cho người dùng cuối.

MVC vs MVP

Cách bạn có thể thấy sơ đồ của MVP rất giống với MVC

MVC là một bước tiến, nhưng nó vẫn được đánh dấu bằng sự vắng mặt hoặc im lặng về một số điều.

Trong khi đó, World Wide Web phát triển và nhiều thứ trong cộng đồng nhà phát triển đã phát triển. Ví dụ, các lập trình viên bắt đầu sử dụng Ajax và chỉ tải các phần của trang thay vì toàn bộ trang HTML cùng một lúc.

Trong MVC tôi nghĩ không có gì để chỉ ra rằng Bộ điều khiển không nên biết việc triển khai cụ thể của Chế độ xem (vắng mặt).

HTML là một phần của lớp View và nhiều trường hợp bị câm. Trong một số trường hợp, nó chỉ nhận các sự kiện từ người dùng và hiển thị nội dung trực quan của GUI.

Khi các phần của các trang web bắt đầu được tải vào các phần, phân đoạn này đã dẫn theo hướng duy trì trạng thái Chế độ xem và nhu cầu lớn hơn về phân tách trách nhiệm logic trình bày.

Logic trình bày là logic điều khiển cách hiển thị UI và cách các thành phần UI tương tác với nhau. Một ví dụ là logic điều khiển khi chỉ báo tải sẽ bắt đầu hiển thị / hoạt hình và khi nào nên dừng hiển thị / hoạt hình.

Trong MVP và MVVM, Lớp xem sẽ bị câm như không có logic hay trí thông minh nào trong đó và trong iOS, Trình điều khiển xem phải là một phần của Lớp xem. Thực tế là View bị câm có nghĩa là ngay cả logic trình bày cũng nằm ngoài lớp View.

Một trong những vấn đề của MVC là nó không rõ ràng về logic trình bày nên ở đâu. Anh chỉ đơn giản là im lặng về điều đó. Logic trình bày nên ở trong lớp View hay trong Layer Model?

Nếu vai trò Model Model là chỉ cung cấp dữ liệu dữ liệu thô, thì điều đó có nghĩa là mã trong Chế độ xem sẽ là:

Hãy xem xét ví dụ sau: chúng tôi có một Người dùng, với tên và họ. Trong Chế độ xem, chúng tôi cần hiển thị tên người dùng là Tên cuối cùng, Tên gọi đầu tiên (ví dụ: Flor Flores, Tiago Tiết).

Nếu vai trò Model Model là cung cấp dữ liệu thô, thì điều đó có nghĩa là mã trong Chế độ xem sẽ là:

hãy để FirstName = userModel.getFirstName ()
hãy để LastName = userModel.getLastName ()
nameLabel.text = lastName +,, + + FirstName

Vì vậy, điều này có nghĩa là trách nhiệm xử lý logic UI. Nhưng điều này làm cho logic UI không thể kiểm tra đơn vị.

Cách tiếp cận khác là để Model chỉ hiển thị dữ liệu cần hiển thị, ẩn bất kỳ logic nghiệp vụ nào khỏi Chế độ xem. Nhưng sau đó, chúng tôi kết thúc với các Mô hình xử lý cả logic nghiệp vụ và giao diện người dùng. Nó sẽ là đơn vị có thể kiểm tra được, nhưng sau đó Mô hình kết thúc, hoàn toàn phụ thuộc vào Chế độ xem.

hãy đặt tên = userModel.getDisplayName ()
tênLabel.text = tên

MVP rõ ràng về điều đó và logic trình bày vẫn nằm trong Lớp Người trình bày. Điều này làm tăng khả năng kiểm tra của lớp Presenter. Bây giờ Lớp Model và Presenter có thể dễ dàng kiểm tra.

Thông thường trong các triển khai MVP, Chế độ xem được ẩn đằng sau một giao diện / giao thức và sẽ không có tham chiếu nào đến UIKit trong Trình dẫn.

Một điều khác cần ghi nhớ là sự phụ thuộc quá độ.

Nếu Bộ điều khiển có Lớp nghiệp vụ làm phụ thuộc và Lớp nghiệp vụ có Lớp truy cập dữ liệu làm phụ thuộc, thì Bộ điều khiển có phụ thuộc bắc cầu cho Lớp truy cập dữ liệu. Do việc triển khai MVP thường sử dụng một hợp đồng (giao thức) giữa tất cả các lớp nên nó không phụ thuộc quá độ.

Các lớp khác nhau cũng thay đổi vì những lý do khác nhau và ở mức giá khác nhau. Vì vậy, khi bạn thay đổi một lớp, bạn không muốn điều này gây ra hiệu ứng / vấn đề thứ cấp trong các lớp khác.

Các giao thức ổn định hơn các lớp. Các giao thức ẩn các chi tiết triển khai và với các hợp đồng, do đó có thể thay đổi các chi tiết triển khai của một lớp mà không ảnh hưởng đến các lớp khác.

Vì vậy, các hợp đồng (giao thức) tạo ra một sự tách rời giữa các lớp.

MVP vs MVVM

Sơ đồ MVVM

Một trong những khác biệt chính giữa MVP và MVVM là trong MVP, Người thuyết trình giao tiếp với Giao diện qua giao diện và trong MVVM, Chế độ xem được định hướng để thay đổi dữ liệu và sự kiện.

Trong MVP, chúng tôi thực hiện liên kết thủ công giữa Người thuyết trình và Chế độ xem bằng Giao diện / Giao thức.
Trong MVVM, chúng tôi thực hiện liên kết dữ liệu tự động bằng cách sử dụng một cái gì đó như RxSwift, KVO hoặc sử dụng một cơ chế với tổng quát và đóng.

Trong MVVM, chúng tôi thậm chí không cần hợp đồng (ví dụ: giao diện java / giao thức iOS) giữa ViewModel và View vì chúng tôi thường giao tiếp thông qua Mẫu thiết kế quan sát.

MVP sử dụng Mẫu Delegate vì Lớp Trình bày Đại biểu đặt hàng cho Lớp xem, do đó, nó cần biết một số thứ về Chế độ xem ngay cả khi đó chỉ là chữ ký giao diện / giao thức. Hãy nghĩ về sự khác biệt giữa Trung tâm thông báo và Đại biểu TableView. Trung tâm thông báo không cần giao diện để tạo kênh liên lạc, nhưng các đại biểu TableView sử dụng giao thức mà các lớp nên thực hiện.

Hãy suy nghĩ về logic trình bày của một chỉ số tải. Trong MVP, người trình bày thực hiện ViewProtocol.showLoadingTheicator. Trong MVVM, có thể có một thuộc tính isLoading trong ViewModel. Lớp View thông qua liên kết dữ liệu tự động phát hiện khi thuộc tính này thay đổi và tự làm mới chính nó. MVP bắt buộc hơn MVVM vì Người trình bày đưa ra các đơn đặt hàng.

MVVM thiên về thay đổi dữ liệu hơn là đơn hàng trực tiếp và chúng tôi thực hiện liên kết giữa thay đổi dữ liệu và xem cập nhật. Nếu sử dụng RxSwift và mô hình lập trình phản ứng chức năng cùng với MVVM, chúng tôi đã làm cho mã thậm chí ít bắt buộc hơn và khai báo nhiều hơn.

MVVM dễ kiểm tra hơn MVP vì MVVM sử dụng Mẫu thiết kế quan sát giúp truyền dữ liệu giữa các thành phần theo cách tách rời.
Vì vậy, chúng ta có thể kiểm tra chỉ bằng cách xem xét các thay đổi trong dữ liệu chỉ bằng cách so sánh hai đối tượng thay vì tạo ra các cuộc gọi phương thức để kiểm tra giao tiếp giữa View và Presenter.

PS: Tôi đã thực hiện một số cập nhật cho bài viết khiến nó phát triển rất nhiều, vì vậy cần phải chia nó thành ba phần. Bạn có thể đọc phần ba ở đây.

Phần hai kết thúc tại đây. Tất cả thông tin phản hồi đều được chào đón. Phần ba sẽ nói về VIPER, VIP, Lập trình phản ứng, Trao đổi, Ràng buộc và Ý thức bối cảnh.

Cảm ơn bạn đã đọc! Nếu bạn thích bài viết này, xin hãy vỗ tay
Để người khác cũng có thể đọc nó :)