不同架构的详细分析
文章目录
- 不同架构的详细分析
- 传统的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 工程
- 打开 Xcode。
- 创建一个新的 iOS App 项目,并命名为
ToDoListDemo
。 - 在项目设置中选择
Swift
语言和Storyboard
用户界面。
2. 创建架构文件和类
在 Xcode 中,创建几个 Group,用于存放 Clean Swift 架构中的各个部分,例如:
Models
、Networking
、Scene
等。在
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]}
在
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)}}
在
Scene
Group 中,创建一个新的 Swift 文件,命名为ToDoListInteractor.swift
。在该文件中创建操作TodoItem
的TodoListInteractor
接口,并提供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()}})}// 添加更新和删除操作方法的默认实现}
在
Scene
Group 中,创建一个新的 Swift 文件,命名为ToDoListPresenter.swift
。在该文件中创建表示获取到的TodoItem
和操作后的TodoListViewModel
的TodoListPresenter
接口,并提供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)}// 添加更新和删除操作方法的默认实现}
在
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) {// 更新用户界面以显示获取到的数据}// 添加更新和删除操作的默认实现}
在
Scene
Group 中,创建一个新的 Swift 文件,命名为ToDoListRouter.swift
。在该文件中创建表示导航逻辑的TodoListRouter
接口,并提供TodoListRouter
的默认实现。protocol TodoListRouterProtocol {func navigateToAddTodoItem()// 添加其他导航方法}class TodoListRouter: TodoListRouterProtocol {weak var viewController: UIViewController?// 实现 TodoListRouterProtocol 中的方法// 可以使用 NavigationController 或 Modal 方式实现不同的导航}
3. 生成视图控制器并完成基本逻辑
在 Xcode 中创建一个新的
UIViewController
类,命名为ToDoListTableViewController
,并在故事板中设置它为启动界面。使用 Interface Builder 创建显示
TodoItem
的列表,并进行相应的布局和设计。注意:在该部分中只包含了部分代码。完整代码可以在我的 GitHub 仓库中找到:
https://github.com/techsleep/clean-swift-todo-app-demo
。在
ToDoListTableViewController.swift
文件中,声明并初始化interactor
、presenter
和router
。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 样式和导航按钮等}}
在
ToDoListTableViewController.swift
文件中,遵循TodoListViewControllerInput
协议,并添加实现所需的操作方法。extension ToDoListTableViewController: TodoListViewControllerInput {func displayAddTodoItemSuccess() {// 在该回调中处理添加待办事项成功后的操作}// 添加更新和删除待办事项操作方法}
在
ToDoListTableViewController.swift
文件中,实现用户输入操作时调用的方法,例如,添加待办事项或者导航到添加页面等。class ToDoListTableViewController: UITableViewController {@IBAction func addButtonClicked(_ sender: Any) {router?.navigateToAddTodoItem()}// 添加其他用户输入操作方法}
在
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. 完成其余的逻辑
在
AddTodoItemViewController
中,定义AddTodoItemViewControllerDelegate
和TodoItem
对象,并通过协议通知TodoListViewController
新的待办事项已经被添加。在
AddTodoItemViewController
中,使用TodoListWorker
对象保存新的待办事项,然后通过协议通知TodoListInteractor
数据已经更新。在
TodoListInteractor
中,使用TodoListPresenter
对象更新用户界面以显示新的待办事项。
在完成以上操作后,您可以使用 Clean Swift 架构编写的 To-do List 应用程序的 demo 就可以正常运行了!