我需要一个类似Hash的类,但不一定需要所有的Hash方法.我已经读过像Hash那样继承核心类并不是一个好主意.无论这是否属实,做这种事情的最佳做法是什么?
# (a) subclass Hash,add new methods and instance variables class Book < Hash def reindex @index = ..... end end # (b) create a new class from scratch,containing a hash,# and define needed methods for the contained hash class Book def initialize(hash) @data = hash end def []=(k,v) @data[k] = v end # etc.... def reindex @index = .... end # (c) like (b) but using method_missing # (d) like (b) but using delegation
解决方法
如果我绝对不希望类似Hash的对象具有某些哈希方法,那么我会将该对象包装在我自己的类中,并且只显示我想要的方法(您的选项b).
如果我希望它通过一些添加的行为来维护其真正的哈希行为,我会在模块中将该行为添加到哈希对象本身,而不是修改核心哈希类:
module SpecialHash def reindex # method def end end my_hash = {} my_hash.extend(SpecialHash) my_hash.reindex #now is defined on my hash
最常见的是,其中一个选项可以帮助我.
一般来说,我倾向于使用模块来扩展类行为而不是类继承,因为我认为它是一种更清晰,更轻量级的方法.创建一个新类总让我感觉我正在为我的域模型添加一个新的“东西”.这很好,正是你想要在无数场景中做的事情,但Ruby的mixin功能为你提供了一个非常好的选择,而你实际上并不需要那么远.
我要处理创建类的主要时间是在对象中是否存在我想要跟踪的其他状态.如果我的添加不是扩展对象的状态,而只是扩展它的行为,那么我几乎总是首先使用模块将该行为混合到该类的现有实例中.
对这类问题的另一个答案也提出了一些值得记住的其他要点:
ruby inheritance vs mixins