Swift函数提前返回实例详解

2020-01-09 00:17:37于海丽
  • 用户是否已经完成入职流程(onboarding flow)。

    我们对这些条件的的实现可能是一系列的 if 和 else 语句,如下所示:

    
    func showInitialViewController() {
    if loginManager.isUserLoggedIn {
    if tutorialManager.isOnboardingCompleted {
    navigationController.viewControllers = [HomeViewController()]
    } else {
    navigationController.viewControllers = [OnboardingViewController()]
    }
    } else {
    navigationController.viewControllers = [LoginViewController()]
    }
    }

    同样的提前返回和 guard 语句可以提升代码可读性,但是现在这种情况不是处理失败情况,而是在不同条件下构建不同 view controller。

    现在来改进这段代码,使用轻量级的工程模式,将构造初始界面移动到专门的函数中,该函数返回匹配条件的view controller。如下所示:

    
    func makeInitialViewController() -> UIViewController {
    guard loginManager.isUserLoggedIn else {
    return LoginViewController()
    }
    
    guard tutorialManager.isOnboardingCompleted else {
    return OnboardingViewController()
    }
    
    return HomeViewController()
    }
    
    func showInitialViewController() {
    let viewController = makeInitialViewController()
    navigationController.viewControllers = [viewController]
    }

    由于 makeInitialViewController 方法是个纯函数(不影响外部状态,固定输入能够得到固定输出),实际上影响外部状态的只有一个地方 navigationController.viewControllers = [viewController] ,(在日常开发中状态如果没有得到很好的控制很容易引起 bug,所以使用更少状态和减少对状态的修改可以一定程度上减少 bug 出现的几率)。

    条件控制

    最后我们来看看,函数如何简化复杂的条件逻辑。我们来构建一个 view controller 来显示社交应用的评论功能,如果满足三个条件则运行用户对评论进行编辑。代码如下:

    
    class CommentViewController: UIViewController {
    override func viewDidLoad() {
    super.viewDidLoad()
    
    if comment.authorID == user.id {
    if comment.replies.isEmpty {
    if !comment.edited {
    let editButton = UIButton()
    ...
    view.addSubview(editButton)
    }
    }
    }
    
    ...
    }
    }