Comparing Design Patterns in Ruby and C#: The Command Pattern (with Robots!)

Filed Under (.Net, Ruby) by John Miller on 28-08-2009

Tagged Under : , , ,

The command pattern is another one of those patterns that we all (whether we realize it or not) see almost every day. It’s commonly used in UI development but it’s a pattern that can be applied in many situations. In rails, ActiveRecord migrations are a perfect example of a command implementation, including “up” and “down” methods for applying and rolling back a migration respectively.

The beauty of the command pattern is it’s ability to encapsulate complicated logic into an easy to use interface. This usually includes:

  1. An ICommand interface or base class that defines the command structure
  2. Concrete command implementations
  3. A receiver that is fed commands to execute. When these commands are actually executed is completely independent of when the receiver is given the commands. It may choose to execute them right away, but it may just as well decide to hold on to them for later use.

Source Code

All of the code in this example is available to download:

Download the Source

Or, you can pull the source directly from github using the below clone url:

git://github.com/johnmiller/CommandPattern.git

Example Overview

The example below involves a robot that moves around on a XY plane similar to:

XYPlane

The robot is given starting coordinates and moves from there. However, it can only perform certain actions:

  1. Move forward
  2. Turn left
  3. Turn right
  4. Reset

As it is given commands, it stores them in an internal collection. If reset is called, it “undo’s” all the commands executed to that point.

C# Example

The ICommand is pretty simple and only includes two method declarations: Execute() and Undo(). All of our concrete commands will need to implement this interface.


public interface ICommand
{
void Execute();
void Undo();
}

Before we create any concrete command classes, let’s take a look at our Robot class. When a new robot is created, we give it a starting location and direction. Notice that when a user calls ExecuteCommand() it immediately performs the instructions given and then stores the command in an internal list. If Reset() is called it iterates through the list in reverse order and calls Undo() on each.


public class Robot
{
public Location Position { get; set; }
public string Direction { get; set; }
private IList<ICommand> _commandsExecuted = new List<ICommand>();

public Robot(Location position, string direction)
{
Position = position;
Direction = direction;
}

public void ExecuteInstruction(ICommand command)
{
command.Execute();
_commandsExecuted.Add(command);
}

public void Reset()
{
foreach (var command in _commandsExecuted.Reverse())
command.Undo();
}
}

The Robot.Position property is of type Location which is a simple class holding the X and Y coordinates.


public class Location
{
public int X { get; set; }
public int Y { get; set; }

public Location(int x, int y)
{
X = x;
Y = y;
}
}

The first command we’ll look at is the MoveForwardCommand which…moves the robot forward one space. But we need to be sure that the robot is moving forward in the direction that it is facing. Internally it contains a list of algorithms for moving the robot depending on the based on it’s current direction. It can also go backwards if Undo() is called.


public class MoveForwardCommand : ICommand
{
private Robot _robot;
private IDictionary<string, Action<Robot>> _moveActions;

public MoveForwardCommand(Robot robot)
{
_robot = robot;
_moveActions = new Dictionary<string, Action<Robot>>
{
{"N", r => r.Position.Y += 1 },
{"E", r => r.Position.X += 1 },
{"S", r => r.Position.Y -= 1 },
{"W", r => r.Position.X -= 1 }
};
}

public void Execute()
{
_moveActions[_robot.Direction](_robot);
}

public void Undo()
{
var oppositeDirection = Compass.GetOppositeDirection(_robot.Direction);
_moveActions[oppositeDirection](_robot);
}
}

The Undo() method uses a class called Compass to find the backwards direction. This is a simple utility class to aid in finding left, right, and opposite directions. To find the direction to the right or left, we find the current direction’s place in the list and move accordingly. Although we need to ensure that when asked to turn right when facing west, it moves to the start of the list to get north (the opposite holds true when turning left when facing north).


public class Compass
{
private static IList<string> _directions = new List<string>{"N", "E", "S", "W"};

public static string GetRightTurnDirection(string direction)
{
if (direction == _directions[3]) return _directions[0];

return _directions[_directions.IndexOf(direction) + 1];
}

public static string GetLeftTurnDirection(string direction)
{
if (direction == _directions[0]) return _directions[3];

return _directions[_directions.IndexOf(direction) - 1];
}

public static string GetOppositeDirection(string direction)
{
var directionToTheRight = GetRightTurnDirection(direction);
return GetRightTurnDirection(directionToTheRight);
}
}

The next set of commands we’ll create will allow the robot to turn left and right. This doesn’t change the space the robot is on, only the direction that it is looking.


public class TurnLeftCommand : ICommand
{
private Robot _robot;

public TurnLeftCommand(Robot robot)
{
_robot = robot;
}

public void Execute()
{
_robot.Direction = Compass.GetLeftTurnDirection(_robot.Direction);
}

public void Undo()
{
_robot.Direction = Compass.GetRightTurnDirection(_robot.Direction);
}
}

public class TurnRightCommand : ICommand
{
private Robot _robot;

public TurnRightCommand(Robot robot)
{
_robot = robot;
}

public void Execute()
{
_robot.Direction = Compass.GetRightTurnDirection(_robot.Direction);
}

public void Undo()
{
_robot.Direction = Compass.GetLeftTurnDirection(_robot.Direction);
}
}

Last, let’s take a look at a unit test that puts the robot to work (the source code linked to earlier in the post includes a lot more unit tests if you’re interested in seeing more!).


[TestFixture]
public class When_a_robot_is_given_multiple_commands
{
private Robot _robot;

[SetUp]
public void EstablishContext()
{
_robot = new Robot(new Location(5, 5), "W");
_robot.ExecuteInstruction(new TurnLeftCommand(_robot));
_robot.ExecuteInstruction(new TurnLeftCommand(_robot));
_robot.ExecuteInstruction(new MoveForwardCommand(_robot));
_robot.ExecuteInstruction(new TurnRightCommand(_robot));
_robot.ExecuteInstruction(new MoveForwardCommand(_robot));
_robot.ExecuteInstruction(new TurnRightCommand(_robot));
_robot.ExecuteInstruction(new MoveForwardCommand(_robot));
_robot.ExecuteInstruction(new MoveForwardCommand(_robot));
_robot.ExecuteInstruction(new TurnRightCommand(_robot));
}

[Test]
public void Should_end_up_at_the_expected_location()
{
Assert.That(_robot.Position.X, Is.EqualTo(4));
Assert.That(_robot.Position.Y, Is.EqualTo(4)); ;
}

[Test]
public void Should_be_facing_the_expected_direction()
{
Assert.That(_robot.Direction, Is.EqualTo("N"));
}

[Test]
public void Should_be_able_to_undo_the_command()
{
_robot.Reset();
Assert.That(_robot.Position.X, Is.EqualTo(5));
Assert.That(_robot.Position.Y, Is.EqualTo(5));
Assert.That(_robot.Direction, Is.EqualTo("W"));
}
}

Ruby Example

With ruby we won’t need to create an abstraction for our command objects, so we’ll jump right into creating our Robot object. Besides basic syntax differences, this is very similar to our C# implementation.


class Robot
attr_accessor :position, :direction

def initialize(position, direction)
@position = position
@direction = direction
@commands_executed = []
end

def execute_instruction(command)
command.execute
@commands_executed << command
end

def reset
@commands_executed.reverse_each{|x| x.undo}
end
end

It also uses a custom Location class to store X and Y coordinates.


class Location
attr_accessor :x, :y

def initialize(x, y)
@x = x
@y = y
end
end

Next up is the MoveForwardCommand. The @move_action variable contains a hash of Proc objects which contain the logic for moving the robot. Note that we use the “call” method to run the proc.


class MoveForwardCommand
def initialize(robot)
@robot = robot
@move_actions = {:N => Proc.new{|r| r.position.y += 1},
:E => Proc.new{|r| r.position.x += 1},
:S => Proc.new{|r| r.position.y -= 1},
:W => Proc.new{|r| r.position.x -= 1}}
end

def execute
@move_actions[@robot.direction].call @robot
end

def undo
opposite_direction = Compass.get_opposite_direction @robot.direction
@move_actions[opposite_direction].call @robot
end
end

Like our C# example, we make use of a custom Compass class to help find our directions. I really like the explicit “first” and “last” properties that come with the array object, seems to make the code a little easier to read.


class Compass
@directions = [:N, :E, :S, :W]

def self.get_right_turn_direction(direction)
return @directions.first if direction == @directions.last
@directions[@directions.index(direction) + 1]
end

def self.get_left_turn_direction(direction)
return @directions.last if direction == @directions.first
@directions[@directions.index(direction) - 1]
end

def self.get_opposite_direction(direction)
direction_to_the_right = get_right_turn_direction direction
get_right_turn_direction direction_to_the_right
end
end

And our commands to allow the robot to turn left and right.


class TurnLeftCommand
def initialize(robot)
@robot = robot
end

def execute
@robot.direction = Compass.get_left_turn_direction @robot.direction
end

def undo
@robot.direction = Compass.get_right_turn_direction @robot.direction
end
end

class TurnRightCommand
def initialize(robot)
@robot = robot
end

def execute
@robot.direction = Compass.get_right_turn_direction @robot.direction
end

def undo
@robot.direction = Compass.get_left_turn_direction @robot.direction
end
end

Last we’ll take a look at a unit test to that puts the robot through it’s paces. (There are also many more tests in the source code download if you’d like see more examples).


describe "When asked to perform multiple commands" do
before(:each) do
@robot = Robot.new Location.new(5,5), :W
@robot.execute_instruction TurnLeftCommand.new(@robot)
@robot.execute_instruction TurnLeftCommand.new(@robot)
@robot.execute_instruction MoveForwardCommand.new(@robot)
@robot.execute_instruction TurnRightCommand.new(@robot)
@robot.execute_instruction MoveForwardCommand.new(@robot)
@robot.execute_instruction TurnRightCommand.new(@robot)
@robot.execute_instruction MoveForwardCommand.new(@robot)
@robot.execute_instruction MoveForwardCommand.new(@robot)
@robot.execute_instruction TurnRightCommand.new(@robot)
end

it "should end up at the expected location" do
@robot.position.x.should == 4
@robot.position.y.should == 4
end

it "should be facing the expected direction" do
@robot.direction.should == :N
end

it "should be able to undo all of the commands" do
@robot.reset
@robot.position.x.should == 5
@robot.position.y.should == 5
@robot.direction.should == :W
end
end

In our next post we’ll take a look at how we can solve the same problem using the State pattern!

kick it on DotNetKicks.com

Share/Save/Bookmark

Comparing Design Patterns in Ruby and C#: The Iterator Pattern

Filed Under (.Net, Ruby) by John Miller on 05-08-2009

Tagged Under : , , ,

Continuing our exploration of design patterns in Ruby and C#, we’re going to dive into the Iterator pattern. Like most design patterns, if you google (or bing) for an example you will run into several different implementations because there are many ways to iterate a collection of objects. In it’s classic (well, classing in the .Net\Java sense) form, the pattern is made of:

  1. An interface defining the iterator. This typically involves two methods: HasNext() and MoveNext().
  2. An concrete iterator implementation
  3. An interface defining an enumerable collection. The only method really needed here would be GetIterator() which will return the iterator object.
  4. A concrete enumerable implementation.

The book Design Patterns in Ruby actually defines that type of implementation as an external iterator. This form gives you a type of hook into the collection that allows you to pull out an object one at a time and work with it externally, away from the insides of the collection. The other type of implementation that it describes is an internal iterator. This form involves a method that passes logic (think anonymous method in C# or code block in Ruby) into a method on the collection. The collection then internally iterates through it’s items and applies the logic on each item. This is a very common way of working with collections in Ruby and is slowly building adoption in C#. As we work through the examples below, we’ll take a look at both external and internal implementations.

The following examples will consist of a used car sales lot which will consist of a collection of vehicles.

C# Example - External Iterator From Scratch

First off, let’s create a basic Vehicle object.


public class Vehicle
{
    public string Name { get; set; }

    public Vehicle(string name)
    {
        Name = name;
    }
}

Our next step is to create an ISimpleIterator interface which we’re going to make generic so we aren’t tied to a specific type of object. It really only needs two methods, HasNext() which will let us know if we’ve reached the end of the collection, and MoveNext() which will return the item in the next position.


public interface ISimpleIterator<T>
{
    bool HasNext();
    T MoveNext();
}

And now we’ll create a concrete implementation of the iterator.


public class SimpleIterator<T> : ISimpleIterator<T>
{
    private int _position = 0;
    private T[] _items;

    public SimpleIterator(T[] items)
    {
        _items = items;
    }

    public bool HasNext()
    {
        return _position < _items.Length;
    }

    public T MoveNext()
    {
        var item = _items[_position];
        _position++;
        return item;
    }
}

Next, let’s create our ISimpleEnumerable interface. We’ll keep this one generic as well since there’s no reason to lock it into only Vehicle objects. Note that it only needs one method that will return a generic ISimpleIterator.


public interface ISimpleEnumerable<T>
{
    ISimpleIterator<T> GetIterator();
}

And our enumerable object will be a SalesLot entity. The GetIterator() method will return a strongly typed vehicle iterator.


public class SalesLot : ISimpleEnumerable<Vehicle>
{
    private Vehicle[] _vehicles = {
                                     new Vehicle("Toyota Camry"),
                                     new Vehicle("Jeep Grand Cherokee"),
                                     new Vehicle("Honda CRV")
                                 };

    public ISimpleIterator<Vehicle> GetIterator()
    {
        return new SimpleIterator<Vehicle>(_vehicles);
    }
}

Let’s see what this code would actually look like if we tried to run it. All we have to do is grab the iterator and wrap it in a while loop.


var salesLot = new SalesLot();
var vehiclesIterator = salesLot.GetIterator();

while (vehiclesIterator.HasNext())
    Console.WriteLine(vehiclesIterator.MoveNext().Name);

Output:

Toyota Camry
Jeep Grand Cherokee
Honda CRV

C# Example - External Iterator Using Built-In IEnumerable Interface

Our design can be hugely simplified by using the IEnumerable interface from the base class library. In the below code sample, our SalesLot object no longer returns an ISimpleIterator, instead it’s passes back a IEnumerator which is also built in the .Net framework. The two GetEnumerator() methods are all that’s needed to fulfill the IEnumerable interface contract. And since all built-in collections implement this interface, we can easily pass that call to the inner list.


public class SalesLot : IEnumerable<Vehicle>
{
    private IEnumerable<Vehicle> _vehicles = new List<Vehicle> {
                                     new Vehicle("Toyota Camry"),
                                     new Vehicle("Jeep Grand Cherokee"),
                                     new Vehicle("Honda CRV")
                                 };

    public IEnumerator<Vehicle> GetEnumerator()
    {
        return _vehicles.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

And using it is just as easy as our earlier example.


var salesLot = new SalesLot();
var enumerator = salesLot.GetEnumerator();

while (enumerator.MoveNext())
    Console.WriteLine(enumerator.Current.Name);

And any class that implements the IEnumerable interface is also able to be iterated over using the foreach construct.


var salesLot = new SalesLot();

foreach (var vehicle in salesLot)
    Console.WriteLine(vehicle.Name); 

C# Example - Adding an Internal Iterator to the SalesLot Class

The previous examples all used external iterators to navigate the collection of cars. But we could have easily used an internal iterator as well. To do this, we need to add a method to the SalesLot object that will allow us to pass in an anonymous method or lambda expression to apply to each vehicle in the collection.


public class SalesLot
{
    private IEnumerable<Vehicle> _vehicles = new List<Vehicle> {
                                     new Vehicle("Toyota Camry"),
                                     new Vehicle("Jeep Grand Cherokee"),
                                     new Vehicle("Honda CRV")
                                 };

    public void ForEach(Action<Vehicle> action)
    {
        foreach (var vehicle in _vehicles)
            action(vehicle);
    }
}

And using it becomes just a couple lines of code.


var salesLot = new SalesLot();
salesLot.ForEach(vehicle => Console.WriteLine(vehicle.Name));

C# Example - Internal Iterator Using the Built-In ForEach List Extension Method

With the addition of Linq, we were given a ForEach extension method on generic lists. Using it is exactly the same as our hand-rolled example.


var salesLot = new List<Vehicle> {
                             new Vehicle("Toyota Camry"),
                             new Vehicle("Jeep Grand Cherokee"),
                             new Vehicle("Honda CRV")
                         };

salesLot.ForEach(vehicle => Console.WriteLine(vehicle.Name));

Ruby Example - External Iterator From Scratch

To get started with our Ruby examples, we’ll create our Vehicle object.


class Vehicle
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

And since Ruby suports duck-typing, we don’t need to create an abstract class or interface to define our iterator. We just need to make sure it has the appropriate methods. Notice that our functions that return a value (such as has_next or move_next) do not need to include the “return” keyword. In Ruby the last line of a mehod is the return value.


class SimpleIterator
  def initialize(items)
    @items = items
    @position = 0
  end

  def has_next
    @position < @items.length
  end

  def move_next
    item = @items[@position]
    @position += 1
    item
  end
end

We are also free to go ahead with creating the SalesLot class without defining an Enumerable abstraction as long as we include a get_iterator method that returns a SimpleIterator.


class SalesLot
  def initialize
    @vehicles = [Vehicle.new("Toyota Camry"), Vehicle.new("Jeep Grand Cherokee"), Vehicle.new("Honda CRV")]
  end

  def get_iterator
    SimpleIterator.new(@vehicles)
  end
end

Actually using the class is very similiar to the C# example.


sales_lot = SalesLot.new
vehicle_iterator = sales_lot.get_iterator

while vehicle_iterator.has_next
  puts vehicle_iterator.move_next.name
end

Output:

Toyota Camry
Jeep Grand Cherokee
Honda CRV

Ruby Example - Creating an Internal Iterator Using the Enumerable Module

While external iterators have their place, Rubyists tend to favor using internal iterators when working with collections. We could easily tack on our own for_each method to the SalesLot object (as we did in the C# example) but instead let’s jump straight into some of the cool things we can leverage in the library. Ruby ships with a handy module called Enumerable that we can include on our SalesLot object which will give us a lot of functionality for free. To use it, we just need to include the Enumerator module and add an “each” method that accepts a code block.


class SalesLot
  include Enumerable

  def initialize
    @vehicles = [Vehicle.new("Toyota Camry"), Vehicle.new("Jeep Grand Cherokee"), Vehicle.new("Honda CRV")]
  end

  def each(&amp;amp;amp;amp;amp;block)
    @vehicles.each(&amp;amp;amp;amp;amp;block)
  end
end

To be able to take advantage of the features given to us from the Enumerable module, our Vehicle needs to add a method defining the “<=>” comparison operator. This method accepts another Vehicle record to compare to and will return -1, 0, or 1 depending on whether the receiver is less than, equal to, or greater than the vehicle being passed in as an argument. For those of you familiar with the IComparable interface in .Net, this works exactly the same way.


class Vehicle
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def <=>(other)
    @name <=> other.name
  end
end

And now we can iterate through our collection in just a couple of lines.


sales_lot = SalesLot.new
sales_lot.each {|vehicle| puts vehicle.name}

But that’s just the tip of the iceberg. We are given a lot of added functionality that allows us to search and sort vehicles in the sales lot.


sales_lot.include? "Ford Escape"
sales_lot.find_all {|vehicle| vehicle.name.length > 12}
sales_lot.sort

And this functionality is available when working with arrays which allows us to do a lot of work with our collections without having to write much code.


vehicles = [Vehicle.new("Toyota Camry"), Vehicle.new("Jeep Grand Cherokee"), Vehicle.new("Honda CRV")]
vehicles.each {|vehicle| puts vehicle.name}

While the iterator pattern may look complex in it’s natural form, both Ruby and C# give us a lot of capabilities out of the box. Neither need much (if any) customization to do advanced work with collections.

Next time, we’ll check out the Command pattern!

kick it on DotNetKicks.com

Share/Save/Bookmark

Comparing Design Patterns in Ruby and C#: The Composite Pattern

Filed Under (.Net, Ruby) by John Miller on 22-07-2009

Tagged Under : , , ,

In the last post of the series, we took a look at the Observer pattern. This time we’re going to explore the Composite pattern. The Composite pattern gives us the ability to take a complex procedure that may involve many steps and turn it into something that is simple for consumers to use.

The classic definition of the Composite pattern involves three pieces: Component, Leaf, and Composite Component. The component defines the interface that the units (leaves and\or composite components) must implement. A leaf is an implementation of a component that performs work. The composite component also implements the component interface but that’s where the similarities end. Under the covers, it contains a collection of components which could be leaves on nested composites. When an interface method is called, it delegates the call to it’s child components. This may sound more complicated than it actually is. Let’s take a look at an example to see how this could work.

C# Example

In this example, we’re going to take the process of changing a car’s oil and break it down to a group of independent tasks. Following our definition above, let’s define an IComponent interface. Per the contract of this interface, all of our “task” objects will need to include a PerformTask() method.


public interface IComponent
{
    void PerformTask();
}

Next, we’re going to create a base class for the tasks that are made up of a collection of child tasks. Notice that although it implements the PerformTask() method of the IComponent interface, it actually delegates the work to it’s child components.


public abstract class CompositeComponent : IComponent
{
    private IList<IComponent> _tasks = new List<IComponent>();

    public void PerformTask()
    {
        foreach (var task in _tasks)
            task.PerformTask();
    }

    public void AddTask(IComponent task)
    {
        _tasks.Add(task);
    }

    public void RemoveTask(IComponent task)
    {
        _tasks.Remove(task);
    }
}

Now let’s create our first needed task (aka. leaf). This one represents the draining of the old oil in the vehicle.


public class DrainOldOilTask : IComponent
{
    public void PerformTask()
    {
        Console.WriteLine("Draining old oil.");
    }
}

The next step is to replace the oil filter which is made of two steps, removing the old filter and installing the new one. To demonstrate this, we’ll create a new CompositeComponent subclass.


public class RemoveOldFilterTask : IComponent
{
    public void PerformTask()
    {
        Console.WriteLine("Removing old filter.");
    }
}

public class InstallNewFilterTask : IComponent
{
    public void PerformTask()
    {
        Console.WriteLine("Installing new filter.");
    }
}

public class ReplaceFilterTask : CompositeComponent
{
    public ReplaceFilterTask()
    {
        AddTask(new RemoveOldFilterTask());
        AddTask(new InstallNewFilterTask());
    }
}

Last, we need to create a task for adding the new oil as well as a composite “ChangeOil” task that ties it all together. Notice that the ChangeOil object is composed of both regular tasks (DrainOilTask and AddNewOilTask) as well as a composite task (ReplaceFilterTask).


public class AddNewOilTask : IComponent
{
    public void PerformTask()
    {
        Console.WriteLine("Adding new oil.");
    }
}

public class ChangeOil : CompositeComponent
{
    public ChangeOil()
    {
        AddTask(new DrainOldOilTask());
        AddTask(new ReplaceFilterTask());
        AddTask(new AddNewOilTask());
    }
}

Now the entire process is a simple method call.


new ChangeOil().PerformTask();

Output
Draining old oil.
Removing old filter.
Installing new filter.
Adding new oil.

Ruby Example

With Ruby, we no longer need to define a component interface. We just need ensure that our classes define a perform_work() method. We will, however, want to create a base class for our composite components.


class CompositeComponent
  def initialize
    @tasks = []
  end

  def perform_task
    @tasks.each {|task| task.perform_task}
  end

  def add_task(task)
    @tasks << task
  end

  def remove_task(task)
    @tasks.delete task
  end
end

Now we’ll create our task objects. Besides basic syntax, the structure of these classes are pretty much the same C# versions.


class DrainOldOilTask
  def perform_task
    puts "Draining old oil."
  end
end

class RemoveOldFilterTask
  def perform_task
    puts "Removing old filter."
  end
end

class InstallNewFilterTask
  def perform_task
    puts "Installing new filter."
  end
end

class ReplaceFilterTask < CompositeComponent
   def initialize
     super
     add_task RemoveOldFilterTask.new
     add_task InstallNewFilterTask.new
   end
end

class AddNewOilTask
  def perform_task
    puts "Adding new oil."
  end
end

class ChangeOil < CompositeComponent
   def initialize
     super
     add_task DrainOldOilTask.new
     add_task ReplaceFilterTask.new
     add_task AddNewOilTask.new
   end
end

Using the objects is also very much the same.


ChangeOil.new.perform_task

Output
Draining old oil.
Removing old filter.
Installing new filter.
Adding new oil.

As you can see, implementing the pattern in the two languages is pretty similar. The biggest difference is the lack of need for a component interface within the Ruby example.

Next time, we’ll be looking at the Iterator pattern. Stay tuned!

kick it on DotNetKicks.com

Share/Save/Bookmark

Comparing Design Patterns in Ruby and C#: The Observer Pattern

Filed Under (.Net, Ruby) by John Miller on 15-07-2009

Tagged Under : , , ,

Continuing our comparison of design patterns in Ruby and C#, we’re taking a look at the Observer pattern. With this pattern, we have a subject and a list of observers that are interested in knowing when changes occur on the subject. This happens in a push model, the subject maintains the list observers and notifies each when needed.

In our examples, we’re going to create a Vehicle object that contains a couple of key properties, Mileage and MileageAtLastOilChange. When a new Vehicle instance is created both properties start at zero. As the vehicle’s Drive() method is called and miles are added to it, it notifies any known observers. The MilesUntilNextOilChange property lets others know how long the vehicle can be driven until it should get an oil change. When the PerformOilChangeMethod() is called, the MileageAtLastOilChange property is set to the current mileage and registered observers are notified that changes occurred.

We are also going to create a Dashboard object that will let us know how many miles the vehicle can be driven until it needs it’s next oil change as well as a warning message alerting the driver that it needs a oil change when it reaches 3000 miles.

C# Example

First we’ll create our Vehicle object as well as an IVehicleObserver interface that must be implemented by any Vehicle observers. Note that the Vehicle object contains an AddObserver() that allows observers to register themselves with the Vehicle.


using System.Collections.Generic;

namespace DesignPatterns.ObserverPattern
{
    public class Vehicle
    {
        private IList<IVehicleObserver> _observers = new List<IVehicleObserver>();

        public int Mileage { get; private set; }
        public int MileageAtLastOilChange { get; private set; }
        public int MilesUntilNextOilChange { get { return 3000 - (Mileage - MileageAtLastOilChange); } }

        public Vehicle()
        {
            Mileage = 0;
            MileageAtLastOilChange = 0;
        }

        public void Drive(int miles)
        {
            Mileage += miles;
            NotifyObservers();
        }

        public void PerformOilChange()
        {
            MileageAtLastOilChange = Mileage;
            NotifyObservers();
        }

        public void AddObserver(IVehicleObserver observer)
        {
            _observers.Add(observer);
        }

        private void NotifyObservers()
        {
            foreach (var observer in _observers)
                observer.Notify(this);
        }
    }
}

namespace DesignPatterns.ObserverPattern
{
    public interface IVehicleObserver
    {
        void Notify(Vehicle vehicle);
    }
}

And now we’ll create our Dashboard class which will implement the IVehicleObserver interface. When the Notify() method is called, it updates the Message property to reflect the vehicle’s current status.


namespace DesignPatterns.ObserverPattern
{
    public class Dashboard : IVehicleObserver
    {
        public string Message { get; private set; }

        public Dashboard()
        {
            Message = string.Empty;
        }

        public void Notify(Vehicle vehicle)
        {
            Message = vehicle.MilesUntilNextOilChange <= 0
                      ? "Time for an oil change!"
                      : string.Format("Next oil change is due in {0} miles.", vehicle.MilesUntilNextOilChange);
        }
    }
}

Let’s take a look at how these two will work together.


var dashboard = new Dashboard();
var vehicle = new Vehicle();

vehicle.AddObserver(dashboard);

vehicle.Drive(2000);
Console.WriteLine(dashboard.Message);

vehicle.Drive(1500);
Console.WriteLine(dashboard.Message);

vehicle.PerformOilChange();
Console.WriteLine(dashboard.Message);

vehicle.Drive(1000);
Console.WriteLine(dashboard.Message);

Ruby Example

The Ruby example really isn’t that much unlike the C# version. The big difference is that we don’t need to create an IVehicleObserver interface, we just need to make sure our Dashboard object has a “notify” method that accepts a Vehicle object.


class Vehicle
  attr_reader :mileage, :mileage_at_last_oil_change

  def initialize
    @mileage = 0
    @mileage_at_last_oil_change = 0
    @observers = []
  end

  def drive(miles)
    @mileage += miles
    notify_observers
  end

  def miles_until_next_oil_change
    3000 - (@mileage - @mileage_at_last_oil_change)
  end

  def perform_oil_change
    @mileage_at_last_oil_change = @mileage
    notify_observers
  end

  def add_observer(observer)
    @observers << observer
  end

  private

  def notify_observers
    @observers.each {|observer| observer.notify self}
  end
end

class Dashboard
  attr_reader :message

  def initialize
    @message = ""
  end

  def notify(vehicle)
    @message = vehicle.miles_until_next_oil_change <= 0 ?
                "Time for an oil change!" :
                "Next oil change is due in #{vehicle.miles_until_next_oil_change} miles."
  end
end

And using the objects is very similiar to the C# example as well.


require "dashboard"
require "vehicle"

dashboard = Dashboard.new
vehicle = Vehicle.new

vehicle.add_observer dashboard

vehicle.drive 2000
puts dashboard.message

vehicle.drive 1500
puts dashboard.message

vehicle.perform_oil_change
puts dashboard.message

vehicle.drive 1000
puts dashboard.message

Simplifying Our Objects

Both languages have built-in mechanisms that we can take advantage of that can make implementing the Observer pattern easy.

In .Net, we’re given out-of-the-box event handling. We just need to create a delegate that defines the method our observers will use for receiving notifications. This reduces the need for an IVehicleObserver interface and simplifies our design.


public delegate void MilesChangedHandler(Vehicle vehicle);

public class Vehicle
{
    public int Mileage { get; private set; }
    public int MileageAtLastOilChange { get; private set; }
    public int MilesUntilNextOilChange { get { return 3000 - (Mileage - MileageAtLastOilChange); } }
    public event MilesChangedHandler MilesChangedEvent;

    public Vehicle()
    {
        Mileage = 0;
        MileageAtLastOilChange = 0;
    }

    public void Drive(int miles)
    {
        Mileage += miles;
        NotifyObservers();
    }

    public void PerformOilChange()
    {
        MileageAtLastOilChange = Mileage;
        NotifyObservers();
    }

    private void NotifyObservers()
    {
        if (MilesChangedEvent != null)
            MilesChangedEvent(this);
    }
}

And no changes have to be made to our Dashboard object.


public class Dashboard : IVehicleObserver
{
    public string Message { get; private set; }

    public Dashboard()
    {
        Message = string.Empty;
    }

    public void Notify(Vehicle vehicle)
    {
        Message = vehicle.MilesUntilNextOilChange <= 0
                             ? "Time for an oil change!"
                             : string.Format("Next oil change is due in {0} miles.", vehicle.MilesUntilNextOilChange);
    }
}

Using the classes changes a bit, note how we subscribe to event on the Vehicle object.


var dashboard = new Dashboard();
var vehicle = new Vehicle();

vehicle.MilesChangedEvent += dashboard.Notify;

vehicle.Drive(2000);
Console.WriteLine(dashboard.Message);

vehicle.Drive(1500);
Console.WriteLine(dashboard.Message);

vehicle.PerformOilChange();
Console.WriteLine(dashboard.Message);

vehicle.Drive(1000);
Console.WriteLine(dashboard.Message);

Ruby also has some built goodness to make our work a little easier. We are actually given an Observable module that we can add to our Vehicle class that will handle the adding, removing, and notifying of observers. The only minor addition we need to add to our object is the a call to the “changed” method when we want to indicate that our object’s state has changed.


require "observer"

class Vehicle
  include Observable

  attr_reader :mileage, :mileage_at_last_oil_change

  def initialize
    @mileage = 0
    @mileage_at_last_oil_change = 0
    @observers = []
  end

  def drive(miles)
    @mileage += miles
    changed
    notify_observers self
  end

  def miles_until_next_oil_change
    3000 - (@mileage - @mileage_at_last_oil_change)
  end

  def perform_oil_change
    @mileage_at_last_oil_change = @mileage
    changed
    notify_observers self
  end
end

To use the module, our observers have to have an “update” method so we’ll need to rename our “notify” method on the Dashboard object.


class Dashboard
  attr_reader :message

  def initialize
    @message = ""
  end

  def update(vehicle)
    @message = vehicle.miles_until_next_oil_change <= 0 ?
                "Time for an oil change!" :
                "Next oil change is due in #{vehicle.miles_until_next_oil_change} miles."
  end
end

And our usage stays exactly the same!


require "dashboard"
require "vehicle"

dashboard = Dashboard.new
vehicle = Vehicle.new

vehicle.add_observer dashboard

vehicle.drive 2000
puts dashboard.message

vehicle.drive 1500
puts dashboard.message

vehicle.perform_oil_change
puts dashboard.message

vehicle.drive 1000
puts dashboard.message

That’s it for the Observer pattern, next time we’ll take a look at the Composite pattern.

kick it on DotNetKicks.com

Share/Save/Bookmark

Comparing Design Patterns in Ruby and C#: The Strategy Pattern

Filed Under (.Net, Ruby) by John Miller on 03-07-2009

Tagged Under : , , ,

In the previous post of this series, we looked at how the Template pattern is implemented in both Ruby and C#. In this post, we’ll take a look at the Strategy pattern…one of my favorites.

In it’s classic form, the Strategy pattern consists of a context class and various “strategies” which share a common interface. The context class is given a strategy to which it can delegate work to. Think of it as passing an algorithm to a class. To change the way the class works, change the algorithm you feed it. This makes it really easy to adhere to the open-closed principle which states that an object should be open for extension but closed for modification. We can drastically change how our class operates without changing a line of code in the class itself.

In .Net, the Sort method on generic lists is a perfect example of how the Strategy pattern can be applied. To change how the list is sorted, you simply pass in a method that matches the Comparison<T> delegate or a class that implements IComparer<T>. (See my earlier post on the various ways you can sort a generic list in .Net).

Ruby has a really cool example built in as well with it’s rdoc utility which uses strategies both for distilling documentation from various languages (C, Ruby, etc) and in how it ouputs the documentation (HTML, XML, CHM).

In our examples below, we’re creating a Driver object that has three different properties: DrivingHabit, MilesDriven, and SpeedingTickets. It also has a method “Drive” which accepts the number of hours that the driver should drive as a parameter. The Drive method delegates the actual "driving” logic to the driving habit that it is composed with. A cautious driver follows the speed limit (55mph) and never gets a speeding ticket. A reckless driver, however, travels along at 80mph and gets a speeding ticket every 1/2 hour.

C# Example

For the Strategy pattern to work in a static language, we must first define a contract that the strategies themselves must adhere to as well as the context class. So we’ll start by creating the Driver object and defining the IDrivingHabit interface.


namespace DesignPatterns.StategyPattern
{
    public class Driver
    {
        public IDrivingHabit DrivingHabit { get; set; }
        public int MilesDriven { get; set; }
        public int SpeedingTickets { get; set; }

        public Driver(IDrivingHabit drivingHabit)
        {
            DrivingHabit = drivingHabit;
        }

        public void Drive(int hours)
        {
            DrivingHabit.Drive(this, hours);
        }
    }
}

namespace DesignPatterns.StategyPattern
{
    public interface IDrivingHabit
    {
        void Drive(Driver driver, int duration);
    }
}

Now let’s create our strategies.


namespace DesignPatterns.StategyPattern
{
    public class CautiousDrivingHabit : IDrivingHabit
    {
        public void Drive(Driver driver, int hours)
        {
            driver.MilesDriven =  hours * 55;
        }
    }
}

namespace DesignPatterns.StategyPattern
{
    public class RecklessDrivingHabit : IDrivingHabit
    {
        public void Drive(Driver driver, int hours)
        {
            driver.MilesDriven += hours * 80;
            driver.SpeedingTickets += hours * 2;
        }
    }
}

And to see how this would actually be used, we’ll take a look at the unit tests.


using NUnit.Framework;

namespace DesignPatterns.StategyPattern
{
    [TestFixture]
    public class When_a_cautious_driver_is_on_the_road_for_3_hours
    {
        private Driver granny;

        [SetUp]
        public void EstablishContext()
        {
            granny = new Driver(new CautiousDrivingHabit());
            granny.Drive(3);
        }

        [Test]
        public void Should_move_a_total_of_165_miles()
        {
            Assert.That(granny.MilesDriven, Is.EqualTo(165));
        }

        [Test]
        public void Should_not_receive_any_speeding_tickets()
        {
            Assert.That(granny.SpeedingTickets, Is.EqualTo(0));
        }
    }

    [TestFixture]
    public class When_a_reckless_driver_is_on_the_road_for_3_hours
    {
        private Driver speedRacer;

        [SetUp]
        public void EstablishContext()
        {
            speedRacer = new Driver(new RecklessDrivingHabit());
            speedRacer.Drive(3);
        }

        [Test]
        public void Should_move_a_total_of_240_miles()
        {
            Assert.That(speedRacer.MilesDriven, Is.EqualTo(240));
        }

        [Test]
        public void Should_receive_a_speeding_ticket_for_every_half_hour_on_the_road()
        {
            Assert.That(speedRacer.SpeedingTickets, Is.EqualTo(6));
        }
    }
}

Pretty simple, eh? Let’s take a look at how we would do this in Ruby.

Ruby Example

First, we’ll create the Driver object. So far doesn’t seem that much different from the C# example.


class Driver
  attr_accessor :driving_habit, :miles_driven, :speeding_tickets

  def initialize(driving_habit)
    @driving_habit = driving_habit
    @miles_driven = 0
    @speeding_tickets = 0
  end

  def drive(hours)
    @driving_habit.drive self, hours
  end
end

Next we’re going to jump straight into creating our Strategy classes. Since Ruby supports duck typing, we really have no need to create an object that defines what our strategies should look like. We could define a base DrivingHabit object that included a Drive method that we can override in our implementations, but that would be producing extra code for no added benefit. We’re ok as long as the object we pass in has a Drive method that matches the required signature.


class CautiousDrivingHabit
  def drive(driver, hours)
    driver.miles_driven += hours * 55
  end
end

require 'lib/driver'

class RecklessDrivingHabit
  def drive(driver, hours)
    driver.miles_driven += hours * 80
    driver.speeding_tickets += hours * 2
  end
end

And now we’ll take a look at the corresponding unit tests.


require 'lib/cautious_driving_habit'

describe "When a cautious driver is on the road for 3 hours" do
  before(:each) do
    @granny = Driver.new(CautiousDrivingHabit.new)
    @granny.drive 3
  end

  it "should move a total of 165 miles" do
    @granny.miles_driven.should == 165
  end

  it "should not receive any speeding tickets" do
    @granny.speeding_tickets.should == 0
  end
end

require 'lib/reckless_driving_habit'

describe "When a reckless driver is on the road for 3 hours" do
  before(:each) do
    @speed_racer = Driver.new(RecklessDrivingHabit.new)
    @speed_racer.drive 3
  end

  it "should move a total of 240 miles" do
    @speed_racer.miles_driven.should == 240
  end

  it "should not receive a speeding ticket for every half hour on the road" do
    @speed_racer.speeding_tickets.should == 6
  end
end

Simplifying the Strategy Pattern

For simple scenarios (such as this one) where the strategies are extremely basic, we can actually reduce the need for the strategy classes themselves. In C#, we just need to add an overloaded Drive method that accepts a delegate that matches the Drive method in the IDrivingHabit interface. (We could have changed the contructor to do this instead.)


public void Drive(int hours, Action<Driver, int> drivingHabit)
{
     drivingHabit(this, hours);
}

And to use it, we pass a lambda expression in that contians our logic.


speedRacer.Drive(3, (driver, hours) =>
                     {
                          driver.MilesDriven += hours*80;
                          driver.SpeedingTickets += hours*2;
                     });

We can do something very similiar in Ruby. We’ll create a new method that accepts a code block as a second parameter. Note that we had to create a new name for this method (Ruby doesn’t support method overloading).


def drive_using_habit(hours, &amp;amp;driving_habit)
 driving_habit.call self, hours
end

And the code using this.


@speed_racer.drive_using_habit(3) do |driver, hours|
    driver.miles_driven += hours * 80
    driver.speeding_tickets += hours * 2
end

In the next post, we’ll take a look at a very similiar pattern, the Observer pattern.

kick it on DotNetKicks.com

Share/Save/Bookmark

Comparing Design Patterns in Ruby and C#: The Template Pattern

Filed Under (.Net, Ruby) by John Miller on 24-04-2009

Tagged Under : , , ,

Most of my career has been in .Net development and I’m pretty comfortable applying design patterns in C#, but as I’m learning Ruby, I was finding it difficult to figure out how to implement them without creating awkward, hard-to-read code. Recently a local Ruby guru, Nate Klaiber, recommended that I pick up the book Design Patterns in Ruby. Well, he more than recommended it, he actually gave a copy autographed by the author (totally unexpected but very, very appreciated!). He has a thorough review of the book (and many others) on his book review site.

As I read through the book, I’m going to do a series of posts showing examples of how each pattern would be applied in both C# and Ruby. (The book has around a dozen patterns so this will probably take several weeks to get through them all).

The first one we’re going to work through is the Template pattern, which is arguably one of the easiest patterns to learn. The template pattern involves creating a base class with methods that can be overridden by subclasses. The base class itself has a central method that will call the other methods in the object.

In the examples below, we’re going to create two vehicle factory classes, one that creates a vehicle specifically for winter travelling, and another that creates vehicles for summertime cruising.

*Note: I’m certainly no Ruby expert (or C# expert for that matter), but am learning here as I go. If you have a better way to do something, please leave a comment!

C# Example

The template method is all over the .Net framework. A perfect example is ASP.Net’s page lifecycle. You’re given hooks to perform actions during page load, init, etc.

Let’s start by creating our Vehicle class.


using System.Collections.Generic;

namespace DesignPatterns.TemplatePattern
{
    public class Vehicle
    {
        public string SteeringWheel { get; set; }
        public string Tires { get; set; }
        public string Seats { get; set; }
        public string Engine { get; set; }
        public string MakeModel { get; set; }
        public IList<string> Amenities { get; set; }

        public Vehicle()
        {
            Amenities = new List<string>();
        }
    }
}

Next we’ll create our base class. Note that CreateVehicle() is the only public method. The rest are only accessible to objects that derive from this class. And some of the “hook” methods have a default implementation while others are declared abstract and must be overridden by the subclass.


namespace DesignPatterns.TemplatePattern
{
    public abstract class VehicleFactoryBase
    {
        protected Vehicle VehicleUnderConstruction { get; set; }

        protected virtual void AddSteeringWheel()
        {
            VehicleUnderConstruction.SteeringWheel = "Standard Steering Wheel";
        }

        protected virtual void AddTires()
        {
            VehicleUnderConstruction.Tires = "All Season Tires";
        }

        protected virtual void AddSeats()
        {
            VehicleUnderConstruction.Seats = "Cloth Bucket Seats";
        }

        protected virtual void AddAmenities()
        {

        }

        protected abstract void AddEngine();

        protected abstract void AddMakeModel();

        public Vehicle CreateVehicle()
        {
            VehicleUnderConstruction = new Vehicle();
            AddSteeringWheel();
            AddTires();
            AddSeats();
            AddAmenities();
            AddEngine();
            AddMakeModel();
            return VehicleUnderConstruction;
        }
    }
}

Now we’re ready to create our first implementation, a vehicle factory that creates vehicles designed for living in the snow belt.


namespace DesignPatterns.TemplatePattern
{
    public class WinterVehicleFactory : VehicleFactoryBase
    {
        protected override void AddTires()
        {
            VehicleUnderConstruction.Tires = "Snow Tires";
        }

        protected override void AddAmenities()
        {
            VehicleUnderConstruction.Amenities.Add("4 Wheel Drive");
            VehicleUnderConstruction.Amenities.Add("Snow Plow");
        }

        protected override void AddEngine()
        {
            VehicleUnderConstruction.Engine = "4.7L V-8";
        }

        protected override void AddMakeModel()
        {
            VehicleUnderConstruction.MakeModel = "Jeep Grand Cherokee";
        }
    }
}

Our second implementation will be a vehicle factory that creates our summer cruiser.


namespace DesignPatterns.TemplatePattern
{
    public class SummerVehicleFactory : VehicleFactoryBase
    {
        protected override void AddSeats()
        {
            VehicleUnderConstruction.Seats = "Leather Bucket Seats";
        }

        protected override void AddAmenities()
        {
            VehicleUnderConstruction.Amenities.Add("Premium Sound System");
        }

        protected override void AddEngine()
        {
            VehicleUnderConstruction.Engine = "3.7L V6";
        }

        protected override void AddMakeModel()
        {
            VehicleUnderConstruction.MakeModel = "Nissan 370Z Coupe";
        }
    }
}

And finally, below are the unit tests needed to verify both factories creates their vehicles as expected.


using NUnit.Framework;

namespace DesignPatterns.TemplatePattern
{
    [TestFixture]
    public class When_creating_a_winter_vehicle
    {
        private Vehicle winterVehicle;

        [SetUp]
        public void EstablishContext()
        {
            winterVehicle = new WinterVehicleFactory().CreateVehicle();
        }

        [Test]
        public void Should_create_a_Jeep_Grand_Cherokee()
        {
            Assert.That(winterVehicle.MakeModel, Is.EqualTo("Jeep Grand Cherokee"));
        }

        [Test]
        public void Should_have_a_standard_steering_wheel()
        {
            Assert.That(winterVehicle.SteeringWheel, Is.EqualTo("Standard Steering Wheel"));
        }

        [Test]
        public void Should_have_snow_tires()
        {
            Assert.That(winterVehicle.Tires, Is.EqualTo("Snow Tires"));
        }

        [Test]
        public void Should_have_a_V8_engine()
        {
            Assert.That(winterVehicle.Engine, Is.EqualTo("4.7L V-8"));
        }

        [Test]
        public void Should_have_standard_cloth_seats()
        {
            Assert.That(winterVehicle.Seats, Is.EqualTo("Cloth Bucket Seats"));
        }

        [Test]
        public void Should_have_4_wheel_drive()
        {
            Assert.That(winterVehicle.Amenities.Contains("4 Wheel Drive"));
        }

        [Test]
        public void Should_have_a_snow_plow()
        {
            Assert.That(winterVehicle.Amenities.Contains("Snow Plow"));
        }

        [Test]
        public void Should_not_have_any_other_amenities()
        {
            Assert.That(winterVehicle.Amenities.Count, Is.EqualTo(2));
        }
    }
}

using NUnit.Framework;

namespace DesignPatterns.TemplatePattern
{
    [TestFixture]
    public class When_creating_a_summer_vehicle
    {
        private Vehicle summerVehicle;

        [SetUp]
        public void EstablishContext()
        {
            summerVehicle = new SummerVehicleFactory().CreateVehicle();
        }

        [Test]
        public void Should_create_a_Nissan_370Z()
        {
            Assert.That(summerVehicle.MakeModel, Is.EqualTo("Nissan 370Z Coupe"));
        }

        [Test]
        public void Should_have_a_standard_steering_wheel()
        {
            Assert.That(summerVehicle.SteeringWheel, Is.EqualTo("Standard Steering Wheel"));
        }

        [Test]
        public void Should_have_all_season_tires()
        {
            Assert.That(summerVehicle.Tires, Is.EqualTo("All Season Tires"));
        }

        [Test]
        public void Should_have_a_V6_engine()
        {
            Assert.That(summerVehicle.Engine, Is.EqualTo("3.7L V6"));
        }

        [Test]
        public void Should_have_leather_seats()
        {
            Assert.That(summerVehicle.Seats, Is.EqualTo("Leather Bucket Seats"));
        }

        [Test]
        public void Should_have_a_premium_sound_system()
        {
            Assert.That(summerVehicle.Amenities.Contains("Premium Sound System"));
        }

        [Test]
        public void Should_not_have_any_other_amenities()
        {
            Assert.That(summerVehicle.Amenities.Count, Is.EqualTo(1));
        }
    }
}

Ruby Example

Now let’s create the same vehicle class in Ruby. Really impressed with how much smaller this class is!


class Vehicle
  attr_accessor :steering_wheel, :tires, :seats
  attr_accessor :amenities, :engine, :make_model

  def initialize
    @amenities = []
  end
end

Next, we’ll create our base vehicle factory class. It’s worth noting that Ruby doesn’t have an “abstract” keyword. To get the same effect, we’ll raise an exception if an expected method was not overridden in a subclass.


require 'lib/Vehicle'

class VehicleFactoryBase
  def create_vehicle
    @vehicle_under_construction = Vehicle.new
    add_steering_wheel
    add_tires
    add_seats
    add_amenities
    add_engine
    add_make_model
    @vehicle_under_construction
  end

  protected

  def add_steering_wheel
    @vehicle_under_construction.steering_wheel = "Standard Steering Wheel"
  end

  def add_tires
    @vehicle_under_construction.tires = "All Season Tires"
  end

  def add_seats
    @vehicle_under_construction.seats = "Cloth Bucket Seats"
  end

  def add_amenities
  end

  def add_engine
    raise "subclass must include the logic for setting the engine"
  end

  def add_make_model
    raise "subclass must include the logic for setting the make and model"
  end
end

And here’s our first subclass, the winter vehicle factory.


require 'lib/Vehicle'
require 'lib/VehicleFactoryBase'

class WinterVehicleFactory < VehicleFactoryBase
    def add_tires
      @vehicle_under_construction.tires = "Snow Tires"
    end

    def add_amenities
      @vehicle_under_construction.amenities.push "4 Wheel Drive"
      @vehicle_under_construction.amenities.push "Snow Plow"
    end

    def add_engine
      @vehicle_under_construction.engine = "4.7L V-8"
    end

    def add_make_model
      @vehicle_under_construction.make_model = "Jeep Grand Cherokee"
    end
end

Next up is the summer vehicle factory.


require 'lib/Vehicle'
require 'lib/VehicleFactoryBase'

class SummerVehicleFactory < VehicleFactoryBase
    def add_seats
      @vehicle_under_construction.seats = "Leather Bucket Seats"
    end

    def add_amenities
      @vehicle_under_construction.amenities.push "Premium Sound System"
    end

    def add_engine
      @vehicle_under_construction.engine = "3.7L V6"
    end

    def add_make_model
      @vehicle_under_construction.make_model = "Nissan 370Z Coupe"
    end
end

And of course our unit tests.


require 'rubygems'
require "spec"
require 'lib/WinterVehicleFactory'

describe "A newly created vehicle" do
  before(:each) do
    @winter_vehicle = WinterVehicleFactory.new.create_vehicle
  end

  it "should be a Jeep Grand Cherokee" do
    @winter_vehicle.make_model.should == "Jeep Grand Cherokee"
  end

  it "should have a standard steering wheel" do
    @winter_vehicle.steering_wheel.should == "Standard Steering Wheel"
  end

  it "should have snow tires" do
    @winter_vehicle.tires.should == "Snow Tires"
  end

  it "should have a V8 engine" do
    @winter_vehicle.engine.should == "4.7L V-8"
  end

  it "should have standard cloth seats" do
    @winter_vehicle.seats.should == "Cloth Bucket Seats"
  end

  it "should have 4 wheel drive" do
    @winter_vehicle.amenities.should include("4 Wheel Drive")
  end

  it "should have a snow plow" do
    @winter_vehicle.amenities.should include("Snow Plow")
  end

  it "should not have any other amenities" do
    @winter_vehicle.amenities.length.should == 2
  end
end

require 'rubygems'
require "spec"
require 'lib/SummerVehicleFactory'

describe "When creating a summer cruiser" do
  before(:each) do
    @summer_cruiser = SummerVehicleFactory.new.create_vehicle
  end

  it "should be a Nissan 370Z" do
    @summer_cruiser.make_model.should == "Nissan 370Z Coupe"
  end

  it "should have a standard steering wheel" do
    @summer_cruiser.steering_wheel.should == "Standard Steering Wheel"
  end

  it "should have all season tires" do
    @summer_cruiser.tires.should == "All Season Tires"
  end

  it "should have a V6 engine" do
    @summer_cruiser.engine.should == "3.7L V6"
  end

  it "should have leather seats" do
    @summer_cruiser.seats.should == "Leather Bucket Seats"
  end

  it "should have a premium sound system" do
    @summer_cruiser.amenities.should include("Premium Sound System")
  end

  it "should not have any other amenities" do
    @summer_cruiser.amenities.length.should == 1
  end
end

In the next post we’ll look at the strategy pattern. Stay tuned!
kick it on DotNetKicks.com

Share/Save/Bookmark

Exploring the Ruby Koans: Building an Object Proxy

Filed Under (Events, Ruby) by John Miller on 14-04-2009

Tagged Under :

Recently I started working through EdgeCase’s Ruby Koans project as a way to become familiar with the Ruby language. The Koans are a set of unit tests that you need to make pass in order to move on to the next step. In making them pass, you learn about the syntax of the Ruby language as well as some of the commonly used libraries.

To get started, follow the instructions on the Koan’s project page on github. When working through them, keep in mind that it’s not a race. Take your time to really understand what each exercise is meant to teach you.

If you’d like a little help getting started with the Koans, one of the author’s, Jim Weirich, will be helping folks at the next Cleveland Ruby user group meeting. Jim is a leader in the Ruby community (active contributor to both Rake and RubyGems) as well as a phenomenal teacher. If you have the evening free, I’d really recommend coming to hear him talk! And in addition to the awesome upcoming CleRb session with Jim Weirich, one of the local .Net SIGs will be featuring Michael Letterle later in the month who will be speaking on IronRuby. Looking forward to both of these events!

In one of the more challenging exercises, you’re asked to build an object proxy that you can wrap around another object to intercept and track method calls made to the underlying object. Below is the solution I came up with (you may want to quit reading if you plan on doing the exercises yourself!). I’m not sure it’s the most elegant solution but it did get the tests passing!


class Proxy
  def initialize(target_object)
    @object = target_object
    @message_log = {}
  end

  def method_missing(method_name, *args, &amp;amp;amp;amp;block)
    if @object.respond_to?(method_name)
      @message_log[method_name] = number_of_times_called(method_name) + 1
      @object.send(method_name, *args, &amp;amp;amp;amp;block)
    else
      super(method_name, *args, &amp;amp;amp;amp;block)
    end
  end

  def messages
    @message_log.keys.reverse
  end

  def called?(method_name)
    @message_log.key?(method_name)
  end

  def number_of_times_called(method_name)
    @message_log[method_name] || 0
  end
end
DotNetKicks Image

Share/Save/Bookmark

50% off Coupon for JetBrain’s RubyMine

Filed Under (Ruby) by John Miller on 07-04-2009

Tagged Under : ,

JetBrain’s is offering a 50% off coupon for their new Ruby editor, RubyMine. But you have to sign up for the coupon now and they’ll email you a coupon code that you can use when the product is released. Worth signing up for if you’re even the tiniest bit interested in purchasing the release version. They announced that the IDE will run $99 once they go live.

I’ve been running a beta version for a few weeks now and am becoming a big fan. Having key mappings that match Resharper really make the transition back and forth from .Net to Ruby a little less painful.

If you’re interested in following the tool as it progresses, you may want to follow rubymine on twitter.

DotNetKicks Image

Share/Save/Bookmark