Sonntag, 15. Februar 2015

Store documents in MongoDB!

MongoDB has become the synonym for NoSQL databases. It is like the shiny new toy every kid wants to play around with. And that is why it also has become a synonym for abused technology unfortunately.
But MongoDB has not to be blamed for being abused and as long as MongoDB is used in cases for which it is meant to be used, everything is fine. Appropriate use cases are real documents. So whenever the requirement is:
  1. inconsistent data (storing the data as it was at that time, like documenting in its traditional meaning)
  2. ACID transaction for a single document
  3. very flexible object structure, which has to be changeable during runtime
The MongoDB installation on a Linux system is charming easy.
There are several gems for using MongoDB in a Ruby On Rails application under the hood. Mongoid is one of the recommended.
After adding it in the Gemfile:
gem 'mongoid'
a simple BirthCertificate model would look like:
class BirthCertificate
  include Mongoid::Document
  field :name
  field :date_of_birth, type: Date
end
Please note the model was not inherited from ActiveRecord::Base, but includes the Mongoid::Document, which makes it transact with MongoDB under the hood. Furthermore 2 fields were configured; name with the default String type and date_of_birth with Date type. Creating a new birth certificate in the Rails console:
BirthCertificate.create name: 'Robert Redford', 
  date_of_birth: Date.new(1936, 8, 18)
MongoDB also has a console for accessing the database (20150215_development). Starting it from bash:
mongo 20150215_development
and asking it for the created record (Attention, it is NoSQL!):
db.birth_certificates.find()
{
  "_id" : ObjectId("55281a5c616e740db0010000"), 
  "name" : "Robert Redford", 
  "date_of_birth" : ISODate("1936-08-18T00:00:00Z") 
}
If a further attribute had to be added, the class could be enhanced like:
class BirthCertificate
  include Mongoid::Document
  field :name
  field :date_of_birth, type: Date
  field :name_of_father
end
The new field name_of_father was introduced later for some reasons and creating a new birth certificate:
BirthCertificate.create name: 'Jennifer Shrader Lawrence', 
  date_of_birth: Date.new(1990, 8, 15), 
  name_of_father: 'Gary Lawrence'
Listing in MongoDB console again:
db.birth_certificates.find()
{ 
  "_id" : ObjectId("55281a5c616e740db0010000"), 
  "name" : "Robert Redford", 
  "date_of_birth" : ISODate("1936-08-18T00:00:00Z")
}
{
  "_id" : ObjectId("55281c4b616e740db0030000"), 
  "name" : "Jennifer Shrader Lawrence", 
  "date_of_birth" : ISODate("1990-08-15T00:00:00Z"), 
  "name_of_father" : "Gary Lawrence" 
}
makes the difference obvious. The older record has no name_of_father, which is important, because the old record should not be modified in any way. It is a document, which has to remain the same despite any structural evolution.
By the way, database migrations are lapsed for mongoid models.
There is way more to say about MongoDB and its features like aggregation and enterprise requirements like replication and sharding.
The flexibility is inviting, but please keep in mind, using MongoDB only makes sense, if inconistent data is wanted - the characteristic of real documents.

Supported by Ruby 2.2.1, Ruby on Rails 4.1.0 and MongoDB 3.0.2

Sonntag, 8. Februar 2015

Go with the Strategy pattern in Ruby!

Solving varying algorithms with the Template Method pattern is reasonable as long as inheritance is reasonable. Since inheritance also comes with some drawbacks, it should be avoided if possible. Especially when it comes to decoupling classes: prefer delegation.
The Strategy pattern also solves varying algorithms but takes advantage of delegation.
In a nutshell, the varying algorithms are extracted into several classes, which define the so called Strategy objects. Each object has the same named API message receiver, but follows a different strategy how to achieve its goal. Apart from the Strategy objects, there is the particular Context object. It is the context in which the strategy works.
The example Context class:
class Person
  attr_reader :id, :resource_name
  attr_accessor :strategy

  def initialize strategy
    @id = 1 
    @resource_name = 'people'
    @strategy = strategy
  end 

  def request
    strategy.query self
  end 
end
is characterized by some (hard coded for example reasons) values: @id and @resource_name. Furthermore the Person class is a proxy and its objects are persisted somewhere else. They can be requested via different kind of webservices, the different strategies. Adding 2 types of webservices as strategies:
require 'uri'
require 'net/http'
class WebserviceRequest
  attr_reader :domain

  def initialize domain
    uri = URI.parse domain
    @http = Net::HTTP.new uri.host, uri.port
    @http.use_ssl = false
  end 

  def query context
    raise "#{self.class}#query not yet implemented."
  end 
end

class SoapRequest < WebserviceRequest
  def query context
    @http.post "/#{context.resource_name}", 
      soap_body(context) { |c|
          "<m:GetPerson>
            <m:Id>#{c.id}</m:Id>
          </m:GetPerson>"
      }, { 'Host' => @http.address, 'Content-Type' => 'text/xml' }
  end 
private
  def soap_body context, &block
    "<?xml version='1.0'?>
      <soap:Envelope xmlns:soap='http://www.w3.org/2001/12/soap-envelope' soap:encodingStyle='http://www.w3.org/2001/12/soap-encoding'>
        <soap:Body xmlns:m='http://#{@http.address}/#{context.resource_name}'>
          #{yield(context)}
        </soap:Body>
      </soap:Envelope>"
  end
end

class RestRequest < WebserviceRequest
  def query context
    @http.get "/#{context.resource_name}/#{context.id}"
  end
end
There is a SOAP (ugh!) and a REST strategy. Both expect a domain address to be requested:
Person.new(RestRequest.new 'http://localhost').request
=> #<Net::HTTPOK 200 OK readbody=true>
Person.new(SoapRequest.new 'http://localhost').request
=> #<Net::HTTPNotFound 404 Not Found readbody=true>
Both requests send a HTTP request to localhost on port 80 with some parameters. Apparently the SOAP query was not the right strategy in the Person context.
But the pattern is obvious: the person Context object has a Strategy object and sends the query message to it with itself as the parameter. The method itself is the implementation detail, the varying part.
Strategies can be added as many as required. For example a Strategy to query a database:
class SqlRequest
  attr_reader :connection

  def initialize connection
    @connection = connection
  end
  
  def query context
    @connection.execute "SELECT * FROM #{context.resource_name} WHERE ID = #{context.id};"
  end
end
and
Person.new(SqlRequest.new database_connection).request
=> SELECT * FROM people WHERE ID = 1;
The advantage is the complete class decoupling. It only relies on duck typing. Any class can be a Strategy as long as it has the right interface.
Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 1. Februar 2015

Template method in Ruby!

Sharing business logic by inheritance is a common pattern in object oriented programming. But sometimes the piece of logic has very little variances, like:
class Bike
  def start
    "Check 2 tyres. Bike is started!"
  end
end

class Car
  def start
    "Check 4 tyres. Start gasoline engine. Car is started!"
  end
end
and:
Bike.new.start
=> "Check 2 tyres. Bike is started!"
Car.new.start
=> "Check 4 tyres. Start gasoline engine. Car is started!"
Quite static. Both classes seem to have something in common (they can be started and have a number of tyres to be checked before). But at the same point, they are specialized by the number of tyres and in having an engine to be started or none.
The template method pattern is a reasonable option to deal with such small variances. It is one of those patterns defined by the Gang of Four and fairly simple to implement.
The pattern is based on inheritance for the similarities (the template method), whereas the variances are separated by extracting them into appropriate methods, so called hook methods. The template method drives the bit that needs to vary, but it does so by making calls to abstract methods, which are then supplied by the concrete subclasses.
The template pattern is absolutely reasonable, when:
  1. inheritance is reasonable
  2. the logic equality is way more distinct than its variance
The example in a templated manner:
class Vehicle
  def start
    todos = ["Check #{tyres} tyres."]
    todos << "Start #{fuel} engine." if fuel
    todos << "#{self.class} is started!"
    todos.join(' ')
  end
private
  def tyres
    raise 'Called abstract method: tyres'
  end

  def fuel
    raise 'Called abstract method: fuel'
  end
end

class Car < Vehicle
private
  def tyres
    4
  end

  def fuel
    gasoline
  end
end

class Bike < Vehicle
private
  def tyres
    2
  end

  def fuel
    nil
  end
end
Since Ruby does not supply abstract methods, defining exception methods in the base class is common practice in Ruby world.
Even though the generalized start method (template method) now looks more complex, it dries out the repeated similarities and is way more flexible for further subclasses.
Please note the template method pattern only makes sense, when the algorithms are way more alike than different.
Even the refactored result can be improved. Abstract methods are the more static typed language way. It makes more sense for the base class Vehicle to simply supply a default implementation of these methods for the convenience of its subclasses:
class Vehicle
  def start
    todos = ["#{self.class} is started!"]
    todos.unshift "Start #{fuel} engine." if fuel
    todos.unshift "Check #{tyres} tyres." unless tyres.to_i.zero?
    todos.join(' ')
  end
private
  attr_reader :fuel, :tyres
end

class Car < Vehicle
private
  def tyres
    4
  end

  def fuel
    gasoline
  end
end

class Bike < Vehicle
  def tyres
    2
  end
end
and:
Bike.new.start
=> "Check 2 tyres. Bike is started!"
Car.new.start
=> "Check 4 tyres. Start gasoline engine. Car is started!"
Creating a new subclass can take advantage of the existing method structure required by the base class:
class Rocket < Vehicle
private
  def fuel
    "oxydizer"
  end
end
It works like a charm:
Rocket.new.start
=> "Start oxydizer engine. Rocket is started!"
Further articles of interest:

Supported by Ruby 2.1.1