0xSina
0xSina

Reputation: 21553

Ruby modules and classes

I am just starting Ruby and learning the concept of modules. I understand that one use of modules is to better organize your code and avoid name clashes. Let's say I have bunch of modules like this (I haven't included the implementation as that's not important) :

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

and another module:

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

I am going to have a bunch of these modules (10+, for gmail, hotmail, etc...). What I am trying to figure out is, is this the right way to organize my code?

Basically, I am using module to represent a "service" and all services will have a common interface class (base for initializing, action for list of actions and event for monitoring).

Upvotes: 1

Views: 1619

Answers (3)

the Tin Man
the Tin Man

Reputation: 160551

I have some similar code at work, only I'm modeling networking gear.

I took the approach of defining a generic class with the common attributes and methods, including a generic comparator, and then sub-class that for the various models of hardware. The sub-classes contain the unique attributes for that hardware, plus all the support code necessary to initialize or compare an instance of that equipment with another.

As soon as I see the need to write a method similar to another I wrote I think about how I can reuse that code by promoting it to the base-class. Often this involves changing how I am passing parameters, and instead of using formal parameters, I end up using a hash, then pulling what I need from it, keeping the method interface under control.

Because you would have a lot of sub-classes to a base class, it's important to take your time and think out how that base-class should work. As you add sub-classes the task of refactoring the base will get harder because you will have to change other sub-classes. I always find I go down some blind-alleys and have to back up a bit, but as the class matures that should happen less and less.

Upvotes: 2

Aliaksei Kliuchnikau
Aliaksei Kliuchnikau

Reputation: 13719

You are defining families of related or dependent classes here. Your usage of modules as namespaces for these families is correct.

Also with this approach it would be easy to build abstract factory for your classes if they had compatible interface. But as far as I see this is not the case for current classes design: for example Dropbox::Event and CustomURL::Event have completely different public methods.

You can reevaluate design of your classes and see if it is possible for them to have uniform interface so that you can use polymorphism and extract something like BaseEvent and BaseAction so that all Events and Actions will derive from these base classes.

Update: As far as you define services, it might be useful to define top-level module like Service and put all your classes inside this module. It will improve modularity of your system. If in the future you would refactor out some base classes for your modules services, you can put them in the top-level namespace. Then your objects will have readable names like these:

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

Upvotes: 4

Simon Ernst
Simon Ernst

Reputation: 1430

As you will notice soon, there is no 'right way' of organizing code.

There are subtle differences in readability that are mostly subjective. The way you are organizing classes is just fine for releasing your code as a gem. It usually isn't needed in code that won't be included in other peoples projects, but it won't hurt either.

Just ask yourself "does this make sense for someone reading my code who has no idea what my intention is?".

Upvotes: 0

Related Questions