把一个大班分成几个模块,这是一个好的ruby成语吗?
我有一个有很多方法的大班,它开始有点无组织,很难导航。 我想分解成模块,其中每个模块是类和实例方法的集合。 也许是这样的:
更新:我现在已经意识到这是一个很糟糕的例子。 您可能不希望将验证或属性移出核心类。
class Large
include Validations
include Attributes
include BusinessLogic
include Callbacks
end
在阅读了耶胡达关于更好的Ruby成语的文章后,我很好奇别人是如何解决这个问题的。 这是我能想到的两种方法。
第一种方法
module Foo
module Validations
module ClassMethods
def bar
"bar"
end
end
module InstanceMethods
def baz
"baz"
end
end
end
class Large
extend Validations::ClassMethods
include Validations::InstanceMethods
end
end
第二种方法
module Foo
module Validations
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def bar
"bar"
end
end
def baz
"baz"
end
end
class Base
include Validations
end
end
我的问题是:
将课堂分为模块,而诱惑(因为Ruby中的容易),很少是正确的答案。 我通常把诱惑放在模块上,因为代码告诉我它想要被分成更紧密聚焦的类。 一个如此之大的类想要将它分解成多个文件几乎可以保证违反单一责任原则。
编辑:详细阐述为什么将代码分解为模块是一个坏主意:读者/维护者感到困惑。 一个班级应该代表一个紧密集中的概念。 当你需要滚动数百行来查找在长类文件的另一端使用的实例方法的定义时,这已经够糟糕的了。 当遇到实例方法调用并且必须在另一个文件中查找时更糟糕。
在做完Avdi说的之后,在将任何东西放入模块之前,我会做这些事情:
如果1的答案为否,2为是,那么恕我直言,这表明更好地有一个类,而不是一个模块。
另外,我认为在模块中放置属性在概念上是错误的,因为类永远不会共享它们的属性或实例变量,换句话说,它们的内部状态与任何其他类相同。 一个类的属性只属于那个类。
业务逻辑确实属于类本身,如果类A的业务逻辑与类C有一些共同责任,那么需要将它提取到基类中以清除它,而不是将它放入模块中。
尽管包含不同的模块可以起作用,但通常比在多个地方重新开放课程更麻烦。
有一个(非常简单)的宝石,你可以用它来做到这一点,可以这样做:concerned_with
示例(来自自述文件)
# app/models/user.rb
class User < ActiveRecord::Base
concerned_with :validations,
:authentication
end
# app/models/user/validations.rb
class User < ActiveRecord::Base
validates_presence_of :name
end
#app/models/user/authentication.rb
class User < ActiveRecord::Base
def self.authenticate(name, password)
find_by_name_and_password(name, password)
end
end
链接地址: http://www.djcxy.com/p/30683.html
上一篇: Whats a good ruby idiom for breaking up a large class into modules?