实际情况比较复杂,不过遇到问题正面解决我是绝对赞成的
最终更换的方式并不是把子类的代码转移到父类,而是从 [由类控制模式] 改为 [由实例控制模式] 因为顶楼的例子并没有写的很详细,可能产生了误解。无论哪种方式,在 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 代码比较多