美文网首页
iOS 遵循开闭原则的实际案例讨论

iOS 遵循开闭原则的实际案例讨论

作者: 黑羽肃霜 | 来源:发表于2019-04-11 22:16 被阅读0次

案例:

假设现在有一个工具类,目的是把传入页面指定区域渲染成红色

不好的设计

定义一个基类 BaseFlushedViewController: UIViewController,返回一个 flushArea, 供工具类进行染色。

class FlushHelper {
    static func flush(_ viewController: BaseFlushedViewController) {
        viewController.flushArea().backgroundColor = .red
    }
}

class BaseFlushedViewController: UIViewController {
    func flushArea() -> UIView {
        return view
    }
}

那么我们传入的参数必须是他的子类,而且由于每个页面可能需要刷新的视图是不同的,我们理论上应该重写他的 flushArea 方法

这样做的问题有两个:

  • 新建的页面类可能会忘记重写该方法
  • 如果需要传入的页面是一个 UINavigatiionControllerUITabbarController呢?(有可能我现在要渲染导航栏或底部标签栏),那么我还要再在工具类中新增两个接口适应。这显然不是我们想要的
class FlushHelper {
    static func flush(_ viewController: BaseFlushedViewController) {
        viewController.flushArea().backgroundColor = .red
    }
    
    static func flush(_ viewController: BaseFlushedNavViewController) {
        viewController.flushArea().backgroundColor = .red
    }
    
    static func flush(_ viewController: BaseFlushedTabViewController) {
        viewController.flushArea().backgroundColor = .red
    }
}

class BaseFlushedViewController: UIViewController {
    func flushArea() -> UIView {
        return view
    }
}

class BaseFlushedNavViewController: UINavigationController {
    func flushArea() -> UIView {
        return view
    }
}

class BaseFlushedTabViewController: UITabBarController {
    func flushArea() -> UIView {
        return tabBar
    }
}

面相接口的设计

定义一个协议

protocol Flushable {
    func flushArea() -> UIView
}

class FlushHelper {
    static func flush(_ viewController: UIViewController & Flushable) {
        viewController.flushArea().backgroundColor = .red
    }
}

class SomeViewController: UIViewController, Flushable {
    func flushArea() -> UIView {
        return view
    }
}

class SomeNavViewController: UINavigationController, Flushable {
    func flushArea() -> UIView {
        return navigationBar
    }
}

class SomeFlushedTabViewController: UITabBarController, Flushable {
    func flushArea() -> UIView {
        return tabBar
    }
}

将工具类的接口统一成 UIViewController & Flushable

这样做的好处:

  • 调用工具类接口时,十分明确的知道传入的页面要去实现 flushArea 方法,不存上文提到的在继承之后忘记重写的情况
  • 适配所有的 UIViewController 及其子类。不需要工具类再开放额外的接口

比较

看起来面向接口的方法和使用基类的方法相比,只是工具类中的接口统一成了一个。但实际上,面向接口的方法中,SomeNavViewControllerSomeFlushedTabViewController 都是 UIViewController 的一种特例。而使用基类的实现方法中,三种 Base 类则是平级的基类,是为了覆盖所有的页面类型。

假设如果有一种新的导航页面,那么面向基类的方法,就还要去新增一个新的基类覆盖这个特例,面向接口的则只需要扩展出一个新的类型即可,工具类接口不需要新增。

以上的思想,就是面向对象设计规则中 开闭原则的一种体现。

相关文章

  • iOS 遵循开闭原则的实际案例讨论

    案例: 假设现在有一个工具类,目的是把传入页面指定区域渲染成红色 不好的设计 定义一个基类 BaseFlushed...

  • 面向对象设计-开闭原则

    一、开闭原则解决的问题 首先不对开闭原则下定义,先看一个不遵循开闭原则的例子。 你自己组装电脑主机,首先购买各种配...

  • iOS 六大设计原则

    iOS六大设计原则:单一职责原则(Single Responsibility Principle)、开闭原则(Op...

  • 工厂方法

    工厂方法 针对上面的简单工厂,在增加新的支付方式时需要修改原有的代码,可能与开闭原则相违背,工厂方法遵循了开闭原则...

  • 手写cache框架

    是否需要兼容,是否可扩展--原生js 遵循开闭原则 扩展性 应用简单 面向接口的设计

  • 2022-01-02 设计原则--开闭原则与里式替换总结

    开闭原则(OCP) 开闭原则(OCP)开闭原则的英文全称是 Open Closed Principle,简写为 O...

  • OOP程序设计规则

    开闭原则(Open-Closed Principle,OCP) 开闭原则是这七大设计原则中最常见、最基本的开闭原则...

  • 行为模式之策略模式

    总纲 设计原则:遵循单一职责、依赖倒置、迪米特、开闭原则 常用场景:算法或者策略需要经常替换 使用概率:60% 复...

  • iOS开闭原则和替换原则

    什么叫开闭原则? 六大模式设计原则之一的开闭原则是比较重要的,开闭原则其实就是“抽象构建框架,实现扩展细节...

  • 开闭原则

    个人博客原文:开闭原则 设计模式六大原则之六:开闭原则。 简介 姓名 :开闭原则 英文名 :Open Closed...

网友评论

      本文标题:iOS 遵循开闭原则的实际案例讨论

      本文链接:https://www.haomeiwen.com/subject/dskfwqtx.html