不同架构的详细分析

文章目录

  • 不同架构的详细分析
    • 传统的MVC架构
    • MVVM架构
    • VIPER架构
    • Clean Swift(也称为 VIP)架构
      • demo
      • 1. 创建 Xcode 工程
      • 2. 创建架构文件和类
      • 3. 生成视图控制器并完成基本逻辑
      • 4. 完成其余的逻辑

传统的MVC架构

**传统的MVC架构将系统分成三个部分:模型(Model)、视图(View)和控制器(Controller)。**模型表示数据和数据处理逻辑;视图表示用户界面;控制器接收用户输入并处理真正的动作。该架构的优点是简单易懂,容易开发和维护;缺点是当应用规模变大时,会出现控制器臃肿、业务逻辑混杂的问题,不利于代码重用和维护。

MVVM架构

**MVVM架构将系统分成三个部分:视图(View)、视图模型(ViewModel)和模型(Model)。**视图负责渲染和用户输入;视图模型处理逻辑并更新视图;模型则与数据相关。通过数据绑定机制,视图模型可以直接将改变反映到视图中,从而实现了低耦合、高可复用性的特点。缺点是实现复杂,需要实现双向数据绑定,代码量相对较多。

VIPER架构

** VIPER架构将系统分为五个部分:视图(View)、表示器(Presenter)、交互器(Interactor)、实体(Entity)和路由(Router)。**表示器负责将用户的操作解析成交互器可执行的操作;交互器负责执行具体的业务逻辑并返回结果给表示器;实体存储实际的业务逻辑,路由负责模块之间的路由和导航。该架构实现了单一职责原则(SRP),代码复用性高,且易于维护。缺点是分层过于细致,代码量稍多,有一定的上手难度。

Clean Swift(也称为 VIP)架构

** Clean Swift将系统分为六个部分:视图控制器(ViewController)、表示器(Presenter)、业务逻辑处理器(Interactor)、实体(Entity)、请求(Request)和响应(Response)。**Clean Swift 原则上是 VIPER 的变种,该架构推崇单一责任原则(SRP),实现了职责分离的目标,同时保证代码的可测试性和可维护性。在 Clean Swift 中,视图控制器只负责管理界面的生命周期和 UI 事件的处理,而将实际业务逻辑和数据处理都放在表示器、业务逻辑处理器和实体等组件中。该架构优点是职责分层明确,代码简洁可读,易于阅读和维护;同时提供了统一的请求、响应和错误处理接口,有利于提高代码复用性和可测试性。缺点是需要遵循约定式的编程规范。

demo

以下是使用 Clean Swift 架构编写的一个简单的 To-do List 应用程序的 demo,其包括了添加、查看、编辑和删除待办事项等功能。

1. 创建 Xcode 工程

  1. 打开 Xcode。
  2. 创建一个新的 iOS App 项目,并命名为ToDoListDemo
  3. 在项目设置中选择 Swift 语言和 Storyboard 用户界面。

2. 创建架构文件和类

  1. 在 Xcode 中,创建几个 Group,用于存放 Clean Swift 架构中的各个部分,例如:ModelsNetworkingScene 等。

  2. Scene Group 中,创建一个新的 Swift 文件,命名为 ToDoListModels.swift。在该文件中定义应用程序中使用的所有必要类型、结构体和模型。

    // 创建 TodoItem 结构体struct TodoItem {var id: Intvar title: Stringvar description: String?var isCompleted: Boolvar date: Date?}// 创建 TodoListViewModel 结构体struct TodoListViewModel {var items: [TodoItem]}
  3. Scene Group 中,创建一个新的 Swift 文件,命名为 ToDoListWorker.swift。该文件将包含执行网络请求和数据持久化的代码。

    protocol TodoListWorkerProtocol {func fetchItems(completion: ([TodoItem]) -> Void)func saveItem(_ item: TodoItem, completion: @escaping (Bool) -> Void)func deleteItem(_ item: TodoItem, completion: @escaping (Bool) -> Void)}class TodoListWorker: TodoListWorkerProtocol {func fetchItems(completion: ([TodoItem]) -> Void) {// 在此处执行网络请求或者数据持久化操作// 返回获取到的 TodoItem 数据}func saveItem(_ item: TodoItem, completion: @escaping (Bool) -> Void) {// 在此处执行网络请求或者数据持久化操作completion(true)}func deleteItem(_ item: TodoItem, completion: @escaping (Bool) -> Void) {// 在此处执行网络请求或者数据持久化操作completion(true)}}
  4. Scene Group 中,创建一个新的 Swift 文件,命名为 ToDoListInteractor.swift。在该文件中创建操作 TodoItemTodoListInteractor 接口,并提供 TodoListInteractor 的默认实现。

    protocol TodoListInteractorProtocol {func fetchTodoList()func addTodoItem(item: TodoItem)// 添加更新和删除操作方法}class TodoListInteractor: TodoListInteractorProtocol {var presenter: TodoListPresenterProtocol?var worker: TodoListWorkerProtocol?func fetchTodoList() {worker?.fetchItems(completion: { [weak self] items inself?.presenter?.presentFetchedTodoList(response: items)})}func addTodoItem(item: TodoItem) {worker?.saveItem(item, completion: { [weak self] success inif success {self?.fetchTodoList()}})}// 添加更新和删除操作方法的默认实现}
  5. Scene Group 中,创建一个新的 Swift 文件,命名为 ToDoListPresenter.swift。在该文件中创建表示获取到的 TodoItem 和操作后的 TodoListViewModelTodoListPresenter 接口,并提供 TodoListPresenter 的默认实现。

    protocol TodoListPresenterProtocol {func presentFetchedTodoList(response: [TodoItem])// 添加更新和删除操作方法}class TodoListPresenter: TodoListPresenterProtocol {weak var viewController: TodoListViewControllerProtocol?func presentFetchedTodoList(response: [TodoItem]) {let viewModel = TodoListViewModel(items: response)viewController?.displayFetchedTodoList(viewModel: viewModel)}// 添加更新和删除操作方法的默认实现}
  6. Scene Group 中,创建一个新的 Swift 文件,命名为 ToDoListViewController.swift。在该文件中创建表示用户界面的 TodoListViewController 和表示用户输入的 TodoListViewControllerInput 接口,并提供 TodoListViewController 的默认实现。

    protocol TodoListViewControllerProtocol: AnyObject {func displayFetchedTodoList(viewModel: TodoListViewModel)}protocol TodoListViewControllerInput {func displayAddTodoItemSuccess()// 添加更新和删除操作方法}class TodoListViewController: UIViewController, TodoListViewControllerProtocol {var interactor: TodoListInteractorProtocol?var router: TodoListRouterProtocol?// 实现 viewDidLoad() 和其他方法func displayFetchedTodoList(viewModel: TodoListViewModel) {// 更新用户界面以显示获取到的数据}// 添加更新和删除操作的默认实现}
  7. Scene Group 中,创建一个新的 Swift 文件,命名为 ToDoListRouter.swift。在该文件中创建表示导航逻辑的 TodoListRouter 接口,并提供 TodoListRouter 的默认实现。

    protocol TodoListRouterProtocol {func navigateToAddTodoItem()// 添加其他导航方法}class TodoListRouter: TodoListRouterProtocol {weak var viewController: UIViewController?// 实现 TodoListRouterProtocol 中的方法// 可以使用 NavigationController 或 Modal 方式实现不同的导航}

3. 生成视图控制器并完成基本逻辑

  1. 在 Xcode 中创建一个新的 UIViewController 类,命名为 ToDoListTableViewController,并在故事板中设置它为启动界面。

  2. 使用 Interface Builder 创建显示 TodoItem 的列表,并进行相应的布局和设计。

    注意:在该部分中只包含了部分代码。完整代码可以在我的 GitHub 仓库中找到:https://github.com/techsleep/clean-swift-todo-app-demo

  3. ToDoListTableViewController.swift 文件中,声明并初始化 interactorpresenterrouter

    class ToDoListTableViewController: UITableViewController {var interactor: TodoListInteractorProtocol?var presenter: TodoListPresenterProtocol?var router: TodoListRouterProtocol?override func viewDidLoad() {super.viewDidLoad()interactor = TodoListInteractor()interactor?.presenter = presenterpresenter = TodoListPresenter()presenter?.viewController = selfrouter = TodoListRouter()router?.viewController = selfinteractor?.fetchTodoList()// 设置 NavigationController 样式和导航按钮等}}
  4. ToDoListTableViewController.swift 文件中,遵循 TodoListViewControllerInput 协议,并添加实现所需的操作方法。

    extension ToDoListTableViewController: TodoListViewControllerInput {func displayAddTodoItemSuccess() {// 在该回调中处理添加待办事项成功后的操作}// 添加更新和删除待办事项操作方法}
  5. ToDoListTableViewController.swift 文件中,实现用户输入操作时调用的方法,例如,添加待办事项或者导航到添加页面等。

    class ToDoListTableViewController: UITableViewController {@IBAction func addButtonClicked(_ sender: Any) {router?.navigateToAddTodoItem()}// 添加其他用户输入操作方法}
  6. TodoListRouter.swift 文件中,实现导航页面的具体逻辑。

    class TodoListRouter: TodoListRouterProtocol {weak var viewController: UIViewController?func navigateToAddTodoItem() {let addTodoItemVC = storyboard.instantiateViewController(withIdentifier: "AddTodoItemViewControllerID") as! AddTodoItemViewControlleraddTodoItemVC.delegate = viewController as? AddTodoItemViewControllerDelegateviewController?.navigationController?.pushViewController(addTodoItemVC, animated: true)}// 添加其他导航}

4. 完成其余的逻辑

  1. AddTodoItemViewController 中,定义 AddTodoItemViewControllerDelegateTodoItem 对象,并通过协议通知 TodoListViewController 新的待办事项已经被添加。

  2. AddTodoItemViewController 中,使用 TodoListWorker 对象保存新的待办事项,然后通过协议通知 TodoListInteractor 数据已经更新。

  3. TodoListInteractor 中,使用 TodoListPresenter 对象更新用户界面以显示新的待办事项。

在完成以上操作后,您可以使用 Clean Swift 架构编写的 To-do List 应用程序的 demo 就可以正常运行了!