用rails框架近一年了,虽然在这个领域还没什么造诣,但作为一个使用rails的'用户',还是有点感想想要分享的,从一开始发现其实写在哪里都是可以的,到瘦controller肥model的概念,再到现在,我发现其实一个很烂的方法,放在控制器和放在模型,没什么区别,这是我在被信息部奖金虐了一下午之后由衷的感想,首先一个没有注释的方法,不管写的怎么样,都是一个烂方法,我读了几百行没有注释的代码之后,唯一的感想就是生无可恋。。。
那么是不是什么方法都应该放在模型里面呢?我们都很喜欢往自己的class里面添加方法,感觉一个class里面的内容越多,这个class就一定很有价值,真的是这样吗?我们为什么不提倡随便打开类似于String,Array这样的类,往里面添加自己想要的方法,因为这会把这个类污染(这种行为被称为猴子补丁),那其实对于自己创建的类也应该这样,别人想要往你的类里添加方法,一个最基本的原则就是这个方法是有注释的,否则凭什么往里面添加方法。
这里介绍两个东西,一个是单件方法,一个是module的class_eval方法.
单件方法
实际上,ruby是允许给一个实例对象创建一个方法的
aa = 'this is a string' def aa.is_a_string? 'yes!' end aa.is_a_string? =>'yes!'
这个方法只有aa这个对象可以用,即便是其他String类的对象也不能用!
(实际上所谓的类方法,也不过是这个类的单件方法,因为class本身也只是一个对象)
如此一来,我们在考虑给一个class添加实例方法的时候,就可以思考一下,是不是只有在某个特殊的地方才会用到,这个实例方法在class里面基本不会被调用,那这时候我们就可以只在需要用的地方创建一个单件方法,从而使class可以少写一个实例方法。
除了使用定义单件方法,还有一个方法可以做到不去模型定义方法,那就是在你要使用的地方,打开你的class,然后定义方法,如此一来,这个实例方法就只存在于你要使用的作用域内!然而上次我说过,ruby的作用域门,变量在试图穿过作用域门的时候会立即失效,那如何在一个作用域里面打开一个类呢?使用class_eval即可
def add_method klass, method klass.class_eval do define_method method.to_sym do yield end end end add_method String, 'test' do 'it works!' end 'aaa'.test => 'it works!'
比如exhibition_color这个方法,目前只有这个页面才会用到,那我就没有必要去ProductCategory这个类里面添加实例方法,只要在我要用到的这个页面,打开这个类,添加这个实例方法,如此这个实例方法便只存在于这个页面!
顺便再说一下怎么打开一个类,然后添加类方法
define_method这个方法是Module类的私有方法,所以不能用self.define_method这种显性调用,但是可以用动态派发(send)来强制使用
class Peter end Peter.class_eval do self.class.send :define_method, :test do 'it works!' end end Peter.test => 'it works!'
网友评论