2014-12-12 15 views
8

Có tính đến cấu trúc VIPERKiến trúc VIPER của iOS, ai phải khởi tạo toàn bộ mô-đun?

enter image description here

Tôi có hai mô-đun, A và B. Các module đầu tiên A, qua người dẫn chương trình, muốn thực hiện một hành động mà phải được thực hiện trong các mô-đun B, vì vậy nói với wireframe của nó để làm điều đó. Câu hỏi đặt ra là, ai chịu trách nhiệm khởi tạo toàn bộ mô-đun (xem, tương tác, trình bày ...). Tôi đã xem một số ví dụ với các cách tiếp cận khác nhau:

  • Tạo tất cả các mô-đun ở đầu ứng dụng.
  • Tạo toàn bộ mô-đun trong khung dây của mô-đun, vì vậy trong trường hợp này là một phương pháp lớp của các mẫu instantire BWireframe tất cả mô-đun B.

Có tính đến khung dây chịu trách nhiệm định tuyến, nó cũng có trách nhiệm tạo mô-đun của nó không?

+0

Nói chung tôi thích Wireframe để tạo mô-đun, Nếu chúng ta tạo tất cả các mô-đun lúc bắt đầu thì nếu có nhiều mô-đun thì nó không có ý nghĩa, Vì vậy, tôi đồng ý rằng cách tiếp cận thứ hai tốt hơn. – Abhishek

Trả lời

15

TL; DR: Tôi khuyên bạn nên sử dụng khung DI như Typhoon và để điều đó xử lý việc khởi tạo.

Lý do bạn có thể không muốn wireframes của bạn instantiating tất cả mọi thứ trong một mô-đun VIPER (Xem, Presenter, Interactor, DataManager) là bạn sẽ tạo phụ thuộc trực tiếp cho mỗi thành phần.

Các phụ thuộc làm cho phần mềm có khả năng chống thay đổi: nếu chúng ta nghĩ đến nó bằng mũ onion architecture/hexagonal architecture của chúng tôi, khung dây sẽ vượt qua ranh giới của ít nhất hai lớp hành của bạn bằng cách biết không chỉ khung nhìn mà còn dữ liệu giám đốc.

Điều này buộc chúng tôi xử lý wireframes là một lớp cơ sở hạ tầng chung: tức là một thứ gì đó ở lớp ngoài cùng của ứng dụng của bạn.

Tuy nhiên, điều này mâu thuẫn với trách nhiệm khác của khung máy (và thực tế hơn): thực hiện điều hướng. Mặc dù đây vẫn là lớp cơ sở hạ tầng, nhưng nó thuộc về một cách chắc chắn và cụ thể trong UIKit (-presentViewController:, v.v.).

Vì vậy, IMHO, khung dây của VIPER đang hoạt động quá nhiều.

Điều hợp lý duy nhất là để chia hai trách nhiệm:

  1. khởi của các tầng lớp VIPER: bạn có thể giới thiệu một factory, hoặc sử dụng các công cụ DI được thiết kế để giải quyết vấn đề này
  2. làm navigation: đây nằm trong phạm vi của Wireframe.

Ghi chú thêm

Nếu bạn đang tự hỏi "người instantiates module tiếp theo?", Sau đó một lần nữa, IMHO, tôi nghĩ rằng đó là không đúng mà 'wireframe cuộc đàm phán s để Module B' một số Module A s wireframe mặc dù những gì các VIPER post nói.

Lý do là Module A bây giờ sẽ được thực hiện phụ thuộc vào Module B, gây ra sự ghép nối chặt chẽ: điều này đánh bại mục đích của mô-đun. Thảo luận nhiều hơn về chủ đề này tại số VIPER-TODO project at GitHub =]

Hy vọng điều này sẽ hữu ích.

+0

Cảm ơn bạn fatuhoku, điều này đã rất khai sáng. Trong dự án của tôi, tôi có bốn mô-đun và tôi có một số lo ngại về điều này. Bước tiếp theo của tôi sẽ được sử dụng Typhoon, trong phiên bản tiếp theo :) Cảm ơn bạn một lần nữa. – emenegro

+0

Tôi đã học về Typhoon lần đầu tiên từ bài đăng này .... cuộc sống của tôi tốt hơn 1000 lần ngay bây giờ. Tôi nợ bạn một beeer @fatuhoku – SleepsOnNewspapers

+0

@SleepsOnNewspapers Haha. Vui vì tôi có thể giúp đỡ =] – fatuhoku

1

Tôi nghĩ rằng cổng vào vào một mô-đun là wireframe vì vậy tôi đồng ý với cách tiếp cận thứ hai của bạn.

Tạo mô-đun bao gồm việc tạo tất cả các đối tượng của nó và có vẻ như tôi rất lãng phí.

1

Có mã khởi mô-đun trên Router riêng của mình sẽ loại bỏ một loạt các mã lặp lại, đặc biệt cho các dự án lớn. Bạn cần phải tạo các phần mở rộng một lần:

// ReusableView.swift 
 
protocol ReusableView: class {} 
 

 
extension ReusableView { 
 
    static var reuseIdentifier: String { 
 
     return String(describing: self) 
 
    } 
 
} 
 

 

 
// UIViewController.swift 
 
extension UIViewController: ReusableView { } 
 

 

 
// UIStoryboard.swift 
 
extension UIStoryboard { 
 
    func instantiateViewController() -> T where T: ReusableView { 
 
     return instantiateViewController(withIdentifier: T.reuseIdentifier) as! T 
 
    } 
 
}

Và sau đó, để lại mã khởi tạo trên router của mỗi mô-đun VIPER:

// MainSearchRouter.swift 
 
class MainSearchRouter { 
 

 
    // MARK: Properties 
 
    weak var view: UIViewController? 
 

 
    // MARK: Static methods 
 
    static func setupModule() -> MainSearchViewController { 
 
     let viewController = UIStoryboard(name: MainSearchViewController.storyboardName, bundle: nil).instantiateViewController() as MainSearchViewController 
 
     let presenter = MainSearchPresenter() 
 
     let router = MainSearchRouter() 
 
     let interactor = MainSearchInteractor() 
 

 
     viewController.presenter = presenter 
 

 
     presenter.view = viewController 
 
     presenter.router = router 
 
     presenter.interactor = interactor 
 

 
     router.view = viewController 
 

 
     interactor.output = presenter 
 

 
     return viewController 
 
    } 
 
}

Nó có vẻ như rất nhiều bước, nhưng tin tốt: t plugin nói trên cũng tự động hóa điều đó!

+0

Cảm ơn Marcelo, tôi sẽ xem xét điều này, nghe có vẻ thú vị! Cuối cùng tôi đã giải quyết điều này theo cùng một cách, tôi sử dụng một giao thức gọi là 'ModuleFactory' để khởi tạo toàn bộ mô-đun. Bạn có thể xem ví dụ tại đây: https: // github.com/emenegro/space-cells-ios – emenegro

Các vấn đề liên quan