请稍侯

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)
    }
}