我怎样才能在一个额外的功能中外包这种重复的代码味道? iOS Swift 函数

How can I outsource this duplicate code smell in an extra function? iOS Swift Functions

我尝试重构与 DRY 原则相关的重复工作代码。 (Swift 版本 4)您可以下载工作代码项目 here(它不大)。问题是我不知道如何正确地专门为这些函数执行此操作,因为它们使用 ViewController 类 并且我无法管理它来传递它们并实例化它们而不是外包功能。我需要根据 dry 查看改进代码的具体实现,因为我在实现部分失败了,我只知道 dry 原理是干净的,但我不知道如何在实际代码中做到这一点

我有什么:

import Foundation
import UIKit

public final class MainCoordinator {

    var navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
        self.navigationController.setNavigationBarHidden(true, animated: false)
    }

func showHome() {
    var vc: HomeViewController
    var i = 0
    for viewController in navigationController.viewControllers {
        if (viewController.isKind(of: HomeViewController.self)) {
            vc = viewController as! HomeViewController
            navigationController.viewControllers.remove(at: i)
            navigationController.pushViewController(vc, animated: true)
            return
        }
        i+=1
    }

    vc = HomeViewController.instantiate()
    vc.coordinator = self
    navigationController.pushViewController(vc, animated: true)
}

func showDetail() {
    var vc: DetailViewController
    var i = 0
    for viewController in navigationController.viewControllers {
        if (viewController.isKind(of: DetailViewController.self)) {
            vc = viewController as! DetailViewController
            navigationController.viewControllers.remove(at: i)
            navigationController.pushViewController(vc, animated: true)
            return
        }
        i+=1
    }

    vc = DetailViewController.instantiate()
    vc.coordinator = self
    navigationController.pushViewController(vc, animated: true)
}

func showMasterDetail() {
    var vc: MasterDetailViewController
    var i = 0
    for viewController in navigationController.viewControllers {
        if (viewController.isKind(of: MasterDetailViewController.self)) {
            vc = viewController as! MasterDetailViewController
            navigationController.viewControllers.remove(at: i)
            navigationController.pushViewController(vc, animated: true)
            return
        }
        i+=1
    }

    vc = MasterDetailViewController.instantiate()
    vc.coordinator = self
    navigationController.pushViewController(vc, animated: true)
}

}

我想要的东西:

这是一个 sample/pseudo 代码,因为它不起作用。你应该明白我的意思。真正的代码会是什么样子?

import Foundation
import UIKit

public final class MainCoordinator {

//..

func showHome() {
    present(HomeViewController)
}

func showDetail() {
    present(DetailViewController)
}

func showMasterDetail() {
    present(MasterDetailViewController)
}

func present(myClass: Class){

    var vc: myClass
    var i = 0
    for viewController in navigationController.viewControllers {
        if (viewController.isKind(of: myClass.self)) {
            vc = viewController as! myClass
            navigationController.viewControllers.remove(at: i)
            navigationController.pushViewController(vc, animated: true)
            return
        }
        i+=1
    }

    vc = myClass.instantiate()
    vc.coordinator = self
    navigationController.pushViewController(vc, animated: true)
}

}

我要介绍一个Coordinatable协议:

protocol Coordinatable: class {
  var coordinator: MainCoordinator? { get set }
}

class HomeViewController: UIViewController, Coordinatable {
  var coordinator: MainCoordinator?
}

class MainCoordinator {
  func showHome() {
    let viewController = HomeViewController() // Or instantiate any other way
    present(viewController)
  }

  func present<T: UIViewController>(_ viewController: T) where T: Coordinatable {
    // Do whatever you want here
    viewController.coordinator = self
    navigationController.pushViewController(viewController, animated: true)
  }
}