swift中实现一种灵活好用的依
31 October 2023
Swift中实现一种灵活好用的依赖反转的架构设计
import Foundation
//MARK: - protocols
@objc public protocol ViewServiceProtocol: NSObjectProtocol {
@objc var viewService: ViewService { get }
var rootView: UIView { get }
@objc func gotoXXXPage()
func updateXXXData()
}
@objc public protocol ViewControllerInteractable {
func getViewData() -> ViewData
func getViewControllerClosure() -> (() -> UIViewController?)?
}
protocol SomeProtocol {
func doSomething(_ pageName: String)
}
//MARK: - Protocolable: ...
protocol Protocolable: ViewServiceProtocol, ViewControllerInteractable, SomeProtocol {
//empty
}
//MARK: - BaseViewController
class BaseViewController: Protocolable {
//......
var viewData: ViewData {
viewService.viewData
}
}
extension BaseViewController: ViewServiceProtocol {
@objc public var viewService: ViewService {
ViewService()
}
public var roomView: UIView {
self.view
}
lazy var someView: SomeView {
let view = SomeView()
view.getProtocolable = { [weak self] in self }
return view
}
@objc public func gotoXXXPage() {
//empty
}
public func updateXXXData() {
//empty
}
}
extension BaseViewController: ViewControllerInteractable {
public func getViewData() -> ViewData {
self.viewData
}
public func getViewControllerClosure() -> (() -> UIViewController?)?{
{ [weak self] in self }
}
}
extension BaseViewController: SomeProtocol {
func doSomething(_ pageName: String){
//do something
}
}
//MARK: - ViewData
@objc public class ViewData: NSObject {
private var _data: XXXModel?
@objc public var modelsId: String?
@objc public var getPageName: (() -> String?)?
//compute properties
var pageName: String? {
getPageName?()
}
var data: XXXModel? {
_data
}
}
//MARK: - ViewService
@objc public class ViewService: NSObject {
@objc public var pageName: String {
"BaseViewController"
}
@objc public lazy var viewData: ViewData = {
ViewData()
}()
//......
}
//MARK: - SomeView
class SomeView: UIView {
var getProtocolable: (() -> Protocolable?)?
//......
//view inner action
func someClickAction() {
switch getProtocolable?() {
case let vc as AAAViewController:
vc.doSomething(vc.viewService.pageName)
case let vc as BBBViewController:
vc.doSomething(vc.viewService.viewData.pageName)
default:
break
}
}
}
//MARK: - Concrete ViewController
class AAAViewController: BaseViewController {
//......
}
extension AAAViewController {
//override ViewControllerInteractable
override public func getViewData() -> ViewData {
self.viewData.getPageName = { "AAAViewController" }
return self.viewData
}
// override public func getViewControllerClosure() -> (() -> UIViewController?)?{
// { [weak self] in self }
// }
@objc public override func viewDidLoad() {
super.viewDidLoad()
//add subviews - someView
view.addSubview(someView)
}
}
class BBBViewController: BaseViewController {
//......
}
extension BBBViewController {
//override ViewControllerInteractable
override public func getViewData() -> ViewData {
self.viewData.getPageName = { "BBBViewController" }
return self.viewData
}
@objc public override func viewDidLoad() {
super.viewDidLoad()
//add subviews - someView
view.addSubview(someView)
}
}
