Ruby模块和类

时间:2012-01-29 15:16:47

标签: ruby

我刚刚开始使用Ruby并学习模块的概念。我知道模块的一个用途是更好地组织代码并避免名称冲突。假设我有一堆像这样的模块(我没有包含实现,因为这并不重要) :

module Dropbox

  class Base

    def initialize(a_user)
    end

  end  

  class Event < Base

    def newFile?
    end

    def newImage?
    end

  end

  class Action < Base

    def saveFile(params)
    end

  end

end

和另一个模块:

module CustomURL

  class Base

    def initialize(a_user, a_url, a_method, some_args, a_regex)
    end

  end

  class Event < Base

    def initialize(a_user, a_url, a_method, some_args, a_regex)
    end

    def change?
    end

  end

  class Action < Base

    def send_request(params)
    end

  end

end

我将拥有一堆这些模块(10+,用于gmail,hotmail等等)。我想弄清楚的是,这是组织我的代码的正确方法吗?

基本上,我使用模块来表示“服务”,所有服务都有一个公共接口类(用于初始化的基础,用于操作列表的操作和用于监视的事件)。

3 个答案:

答案 0 :(得分:4)

您在这里定义相关或依赖类的系列。您对这些系列使用namespaces模块是正确的。

使用这种方法,如果你的类具有兼容的接口,那么很容易为你的类构建abstract factory。但据我所知,目前的类设计并非如此:例如Dropbox::EventCustomURL::Event具有完全不同的公共方法。

您可以重新评估类的设计,看看它们是否可以使用统一的界面,以便您可以使用polymorphism并提取BaseEventBaseAction之类的内容,以便所有事件和动作将来自这些基类。

更新:就定义 services 而言,定义顶级模块(如Service)并将所有类放在此模块中可能会很有用。它将改善您系统的模块化。如果将来您要为模块服务重构一些基类,可以将它们放在顶级命名空间中。那么你的对象将具有这样的可读名称:

Service::Dropbox::Event
Service::Dropbox::Action
Service::CustomURL::Event
Service::CustomURL::Action
Service::BaseEvent
Service::BaseAction

答案 1 :(得分:1)

我有一些类似的代码在工作,只有我正在建模网络设备。

我采用了使用公共属性和方法定义泛型类的方法,包括通用比较器,然后是各种硬件模型的子类。子类包含该硬件的唯一属性,以及初始化或比较该设备的实例与另一个实例所需的所有支持代码。

一旦我看到需要编写类似于我编写的另一个方法,我就会考虑如何通过将其提升到基类来重用该代码。这通常涉及改变我传递参数的方式,而不是使用形式参数,我最终使用哈希,然后从中拉出我需要的东西,保持方法接口的控制。

因为你有很多基类的子类,所以花点时间思考基类应该如何工作是很重要的。当您添加子类时,重构基础的任务将变得更加困难,因为您将不得不更改其他子类。我总是发现我走下了一些盲道并且不得不支持,但随着课程的成熟,这种情况应该越来越少。

答案 2 :(得分:0)

您很快就会注意到,没有“正确的方法”来组织代码。

可读性方面存在细微差别,主要是主观性的。组织类的方式适合将代码作为gem发布。在代码中通常不需要它不包含在其他人的项目中,但它也不会受到伤害。

请问自己“这对于阅读我的代码而不知道我的意图是什么的人来说是否有意义?”。