继承缺陷以及替代方案

继承的好处

轻松实现代码复用

继承的缺陷

紧耦合

  • 牵一发而动全身。父类的一个改动,会影响所有子类的行为
  • 拔出萝卜带出泥。当在另外的项目里复用某个子类的代码时,要跟着把父类以及所有的相关依赖也复制过去

类爆炸

  • 每当增加一个新feature时,继承体系中的类要翻倍。

究竟哪些场景适合用继承

  • 层级关系明显,功能划分清晰。父类只是给子类提供基础服务,并不涉及子类的业务逻辑

Object并不影响Model, View, Controller的执行逻辑和业务 Object为子类提供基础服务,例如内存计数等

ApiManager并不影响其他的Manager  
ApiManager只是给派生的Manager提供服务而已,ApiManager做的只会是份内的事,对于子类做的事情不参与。

  • 父类的所有变化,都需要在子类中体现,也就是说此时耦合已经成为需求
   Object对类的描述,对内存引用的计数方式等,都是普遍影响派生类的。  
    ApiManager中对于网络请求的发起,网络状态的判断,是所有派生类都需要的。  
    此时,牵一发动全身就已经成为了需求,是适用继承的

不满足以上特点的,慎用继承

继承的替代方案

  • 子类只是使用相同的接口—>protocol
  • 子类只是想在某些时机额外一些自定义的函数—>delegation(AOP中的消息拦截器啊, 以及策略模式中的strategy等都是这种机制)
  • 子类只是给父类增加一些简单功能—>category
    在用类别扩展一个不是你自己的类的时候,在方法前添加前缀是个比较好的习惯做法。
    使用类别还有另外一个风险,那就是,到最后你可能会使用一大堆的类别,连你自己都会失去对代码全局的认识。假如那样的话,创建自定义的类可能更简单一些。
  • 父类是抽象类(不能直接使用),子类提供一些属性配置项来完成对象的setup工作—>使用Configuration Objects
  • 复用某些功能,而不必共享同样的接口—>组合。 组合是替代继承最强大有效的方案

当继承体系超过2层时,你就要好好考虑是否采用继承的方案了。

参考文章

原文地址:https://www.cnblogs.com/mindyme/p/4561347.html