• 实际情况比较复杂,不过遇到问题正面解决我是绝对赞成的

    最终更换的方式并不是把子类的代码转移到父类,而是从 [由类控制模式] 改为 [由实例控制模式] 因为顶楼的例子并没有写的很详细,可能产生了误解。无论哪种方式,在 Base 中都会有个模式属性,只不过一开始我偏向于添加类变量,即

    class Base
      class << self
        attr_accessor :mode
      end
    end
    
    class BizA < Base; end
    class BizB < Base; self.mode = :fast; end
    

    Base中会用当前 class 的 mode 属性做一些分支处理,而 exec 方法的实现纯粹是各自 Biz 自己的业务逻辑,但是 BizB 和 BizA 从 Biz 这一层来看,exec 是完全相同的,只是 mode 不同

    如一开始所说,因为 BizA 和 BizB 并没有上下级关系,我不想直接用继承 其实可以把 mode 类变量变为实例变量(现在也是这么改的),这样就不需要额外定义 BizB 了,只需要在运行时修改 BizA 的 mode 就可以了。但是为一开始不这么做,因为Base中很多地方使用了self.class.name作为外部持久化的值,如果不额外定义 BizB,这些地方就会出问题,于是钻入了牛角尖,当时的想法是 BizB 能复制 BizA 的 exec 方法即可解决了,搜到 stackoverflow 上也有人问类似的问题 https://stackoverflow.com/questions/9294205

  • 但在一个没有 spec 的大型系统中,“大”还是挺成问题的,尤其是改的代码还不是自己实现的情况下

  • 抽走确实不影响继承,但现在已经有很多 Biz 了,相当于要把所有 Biz 内部的 exec 实现,以及 exec 中调用的其他方法也放到新 module 中,改动会比较大,或许可以写个 dsl 来实现?(类似 ruby 内 private 的实现,以下内容为动态生成的 module 中的内容)

    打算换个思路实现了,实际上我是想让 Base 有不同的处理模式,不同模式在 Base 中处理的分支不一样,但不同模式的 exec 实现内容是一样的。给 Base 添加模式属性进行判断,就是需要改动的 Base 代码比较多