Ruby 什么时候使用 module,什么时候使用 class

6233843 · 2012年08月22日 · 最后由 yangman_wenzhu 回复于 2015年03月06日 · 8527 次阅读

一段逻辑既可以做一个 module,也可以做一个 class 老早之前就在纠结这个问题,实在找不出个界限

最近和同事讨论了一下,有了新的认识,和大家讨论一下 1.module 比较关注的是功能方面,它把方法收集在一起,组成一个特殊的上下文,通常表示一种能力,比如 Enumerable。 2.class 就是我们所理解的经典的类,它可以创建实例对象,包含实例变量和类变量,一般通过对象来与外界交流。

除了这些,我认为 class 通常都是逻辑完整的,甚至能在现实世界中找到对应物,而对 module 来说却很难是逻辑完整的,因为 module 只能描述一个特殊的上下文,而这个上下文通常无法组成一个完整的对象,需要被找一个宿主,而这个宿主有可能是 class,也有可能是 module

不知道大家有什么看法?欢迎讨论

需要用于做命名空间或用于 mixin 的时候用 module, 其他时候用 class

当 class 中或多个 class 中有重复代码需要抽象出来时,你会想要一个 module 的东东。 因为不能多重继承,只好用 module 来补偿一下。

另一点我觉得更容易解耦,继承哪个类,你只能选一个,但具体要 include 哪几个 module 你可以根据不同需求选择不同的 module. 有了 autoload 更加能优化性能。

总的一点来说,顺其自然,你当前用什么能达到目的就用啥,过几个月或几个星期,觉得以前的写法不爽时你会自己回来重构的。

module 就像是工具箱,里面的各种工具,就是 class

module 感觉有点像 cpp 里面的抽象类 当然只是类似,其间还是有很多差别的

#4 楼 @xuluan 跟抽象类没关系,ruby 中不搞这概念。ruby 来的是 ducking type。抽象和接口更多的作用是强制约束,目的不是代码复用。

class 比 module 多两个功能,1) 继承,2) 实例化 所以用到这两功能的就 class 用不到就 module

@hhuai 我的意思,就是楼上说的,实例化吧 在 cpp 里面 抽象类是不能实例化的,就像 ruby 里面的 module 一样 当然 这两种语言差别很大,只是一个不恰当的比喻而已

#1 楼 @huacnlee 这倒是一个不错的建议。那该如何判断某段代码需要 mixin 么?简单的观察别的类是否需要 mixin 么?

#2 楼 @hhuai 你说的我明白,但总是在纠结用 class 或 module,尤其是一段代码既可以用调用 module,也可以调用 class 的类方法,就更加纠结,呵呵

#9 楼 @6233843 不了解的时候暂时用 Class 好了,等你 Ruby 再熟悉一些的时候你会慢慢发现,你需要用 Module,那个时候再去了解也不迟

我认同楼主的观点,但是我想说说自己的看法: 我认为,先用 class 去写代码, 当多个 class 的代码逻辑相似的时候, 可以考虑用基类/继承来提取相似的逻辑。

当继承无法实现提取的时候, 比如,有时候,两个 class 代码逻辑相似, 但是,两个 class 的基类不同,而 ruby 又不支持多继承。

所以,这个时候, 就可以考虑使用 module 来实现,相似代码的提取。

#6 楼 @jjym 那怎么确定我需要继承和实例化呢?

#10 楼 @huacnlee 你的意思是当我需要 module mixin 到别的类时,再抽取 module,现在我也是这样做的。但有些情况是模棱两可的,module 可以,class 也可以,这时候我总是靠自己的感觉来判断是否需要 module,但始终觉得这种‘飘渺’的感觉很难说服我自己,所以我希望能找到一个界限。

#11 楼 @ery 同意,从最简单的开始,一步一步重构到最优。

#12 楼 @6233843 你智商这么高,肯定能确定的,要相信自己

#10 楼 @huacnlee 在 Class 中 include module 是不是好方法呢?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号