**传统的MVC架构将系统分成三个部分:模型(Model)、视图(View)和控制器(Controller)。**模型表示数据和数据处理逻辑;视图表示用户界面;控制器接收用户输入并处理真正的动作。该架构的优点是简单易懂,容易开发和维护;缺点是当应用规模变大时,会出现控制器臃肿、业务逻辑混杂的问题,不利于代码重用和维护。
**MVVM架构将系统分成三个部分:视图(View)、视图模型(ViewModel)和模型(Model)。**视图负责渲染和用户输入;视图模型处理逻辑并更新视图;模型则与数据相关。通过数据绑定机制,视图模型可以直接将改变反映到视图中,从而实现了低耦合、高可复用性的特点。缺点是实现复杂,需要实现双向数据绑定,代码量相对较多。
** VIPER架构将系统分为五个部分:视图(View)、表示器(Presenter)、交互器(Interactor)、实体(Entity)和路由(Router)。**表示器负责将用户的操作解析成交互器可执行的操作;交互器负责执行具体的业务逻辑并返回结果给表示器;实体存储实际的业务逻辑,路由负责模块之间的路由和导航。该架构实现了单一职责原则(SRP),代码复用性高,且易于维护。缺点是分层过于细致,代码量稍多,有一定的上手难度。
** Clean Swift将系统分为六个部分:视图控制器(ViewController)、表示器(Presenter)、业务逻辑处理器(Interactor)、实体(Entity)、请求(Request)和响应(Response)。**Clean Swift 原则上是 VIPER 的变种,该架构推崇单一责任原则(SRP),实现了职责分离的目标,同时保证代码的可测试性和可维护性。在 Clean Swift 中,视图控制器只负责管理界面的生命周期和 UI 事件的处理,而将实际业务逻辑和数据处理都放在表示器、业务逻辑处理器和实体等组件中。该架构优点是职责分层明确,代码简洁可读,易于阅读和维护;同时提供了统一的请求、响应和错误处理接口,有利于提高代码复用性和可测试性。缺点是需要遵循约定式的编程规范。
以下是使用 Clean Swift 架构编写的一个简单的 To-do List 应用程序的 demo,其包括了添加、查看、编辑和删除待办事项等功能。
ToDoListDemo
。Swift
语言和 Storyboard
用户界面。在 Xcode 中,创建几个 Group,用于存放 Clean Swift 架构中的各个部分,例如:Models
、Networking
、Scene
等。
在 Scene
Group 中,创建一个新的 Swift 文件,命名为 ToDoListModels.swift
。在该文件中定义应用程序中使用的所有必要类型、结构体和模型。
// 创建 TodoItem 结构体
struct TodoItem {
var id: Int
var title: String
var description: String?
var isCompleted: Bool
var 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 in
self?.presenter?.presentFetchedTodoList(response: items)
})
}
func addTodoItem(item: TodoItem) {
worker?.saveItem(item, completion: { [weak self] success in
if 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 方式实现不同的导航
}
在 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 = presenter
presenter = TodoListPresenter()
presenter?.viewController = self
router = TodoListRouter()
router?.viewController = self
interactor?.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! AddTodoItemViewController
addTodoItemVC.delegate = viewController as? AddTodoItemViewControllerDelegate
viewController?.navigationController?.pushViewController(addTodoItemVC, animated: true)
}
// 添加其他导航
}
在 AddTodoItemViewController
中,定义 AddTodoItemViewControllerDelegate
和 TodoItem
对象,并通过协议通知 TodoListViewController
新的待办事项已经被添加。
在 AddTodoItemViewController
中,使用 TodoListWorker
对象保存新的待办事项,然后通过协议通知 TodoListInteractor
数据已经更新。
在 TodoListInteractor
中,使用 TodoListPresenter
对象更新用户界面以显示新的待办事项。
在完成以上操作后,您可以使用 Clean Swift 架构编写的 To-do List 应用程序的 demo 就可以正常运行了!