Why are you using such an insecure and old browser? Please be aware that this site will not display properly in Internet Explorer 6. You can either upgrade to Internet Explorer 7 or use a proper browser such as Safari, Firefox or Opera.

Cleaning up constants


Posted by Jonathan Conway on 2008-03-27  Comments

When it comes to a Rails or a Merb app I like to make sure there is a clean separation of concerns. One of the ways I do this is modularising the behaviour of an object into mixins.

For example, a movie object might need some logic that relates to video transcoding. Rather than have this explicitly part of the main class I move it into a mixin, this for me makes code that is:

  • easier to read
  • maintainable
  • testable
  • reusable

Of course like everything this requires thought and I’m careful not to go mad with this pattern as the last thing I want is something that resembles the old EJB 2.0 madness where all the business logic was contained in other service objects and all that’s left is an anaemic model in which you need an IDE like Intellij to discover what on earth is going on and where.

When it comes to constants I’ve noticed a few people extolling the virtue’s of putting constants in the environment.rb (dev/test/production) as an easy way of having globally accessible constants. This in my opinion should be avoided at all costs if possible.

Instead I favour putting my constants in either in the model that they relate to as this increases readability and stops pollution/collisions. Or my current favourite method is to group the constants up by context into their own yaml files and have them loaded and accessed from a module. It still keeps my models clean while still keeping my code readable and more maintainable.

For example something like this:


module Tasks
   module Config

    def self.message_queue_ip
      @@message_queue_ip ||= YAML.load_file \
       ("#{Merb.root}/config/tasks_conf.yml") \
        [Merb.environment]['message_queue']
    end

    #Rest of your constants....
   end
end

#Add access it with 
Tasks::Config.message_queue_ip

Of course this is a trivial example but you see how it automatically loads the correct value based upon the current environment without any conditionals. Yep, it’s all pretty much common sense but I still seem to always get handed apps that don’t follow simple rules of good OO design.

blog comments powered by Disqus