Archive

Posts Tagged ‘Polyglot’

GOF Series: Episode #4 [The Builder Pattern] - In IronRuby

November 5th, 2008 Simon Segal 3 comments

So first up let me say that the balance of this series of posts on patterns will be presented using either C# or IronRuby as languages to express the GOF patterns. Why IronRuby you ask? I have taken to learning IronRuby and Silverlight as deeply as possible this year and decided to spice things up for myself by incorporating it in this series of posts. Never fear I will continue to demonstrate most of the remaining patterns in C# but will from time to time present the patterns in both languages. For now however it’s the Builder Pattern exclusively in IronRuby for the dynamic language enthusiasts.

IronRuby is a dynamically typed, object oriented language and runs in the Dynamic Language Runtime. We will demonstrate the builder pattern using IronRuby, Windows Forms and the Ruby In Steel plugin for Visual Studio.Net 2008.

The goal of the Builder Pattern is to separate or abstract away the construction of an object and to allow the same / common construction process to create the object regardless of its representation. The different representations of the object being constructed are created by concrete builders, specifically designed to create one and only one representation of the product class.

The players in the story:

  • The Director

    • Responsible for constructing the Product object via an interface (mixin in the case of this example using IronRuby) implemented by a concrete builder.
  • The Builder

    • Provides the interface (object in this case) that creates the Product(s) constituent parts and is implemented (included as a mixin with IronRuby) by concrete builders.
  • The Concrete Builder

    • Builds the constituent parts of the Product object.
  • The Product

    • The object whose parts are created by the concrete builder.

BuilderPattern

In C# or other statically typed languages such as java, the builder pattern relies on an abstract class design and inheritance. In IronRuby there is no concept of an interface therefore a different approach is required. We can use a mixin to provide the common behavioural aspects and use arguments to diverge the different concrete builders. The construction of the ‘Product’ is abstracted from the ‘Director’ by the ‘Builder’ and it’s Concrete implementations. To obtain different representations of the Product object new concrete builder objects are created. The Builder Pattern creates it’s Product object in parts via the Director and Builders abstract signatures, however an alternate approach with IronRuby is to substitute the abstract class for a mixin.

#Product
class FootballTeam

    def team_id?()
        self.hash
    end

    def team_type_name?()
        @team_type_name
    end

    def team_properties?()
        @team_properties
    end

    def initialize(name)
        @team_type_name = name
        @team_properties = Hash.new(“Staff Role does not exist!”)
    end

end

#Builder
module FootballTeamBuilder

    attr_reader :name
    attr_writer :name

    def footy_team?()
        @footy_team
    end

    def build_init()
        @footy_team = FootballTeam.new(name)
    end

    def build_players(number_of_players)
        @footy_team.team_properties?["Players"] = number_of_players
    end

    def build_ball_shape(shape_of_ball)
        @footy_team.team_properties?["ballshape"] = shape_of_ball
    end

    def build_games_per_season(number_of_games)
        @footy_team.team_properties?["games"] = number_of_games
    end

    def print_team_details()

        attributes =  “****************************” +
            “******************************\r\n”

        attributes += “Created a #{name} team with the “ +
            “following attributes :\r\n”

        @footy_team.team_properties?.each { |k,v|
            attributes += k.to_s + ” “ + v.to_s + “\r\n” }

        attributes += “\n***************************” +
            “*******************************\n”

        return attributes
    end

end

#Concrete Builder”
class AustralianRulesFootballTeamBuilder 

    include FootballTeamBuilder

    def build_all()
        self.name = “Aussie Rules”
        build_init()
        build_ball_shape(“Oval”)
        build_games_per_season(22)
        build_players(18)
    end

end

#Concrete Builder
class RugbyLeagueFootballTeamBuilder

    include FootballTeamBuilder

   def build_all()
        self.name = “Rugby League”
        build_init()
        build_ball_shape(“Oval”)
        build_games_per_season(24)
        build_players(13)
    end

end

#Concrete Builder
class SoccerFootballTeamBuilder

    include FootballTeamBuilder

    def build_all()
        self.name = “Soccer”
        build_init()
        build_ball_shape(“Round”)
        build_games_per_season(44)
        build_players(11)
    end

end

#Director Class
class GoverningBody

    def build_football_team(football_team_builder)
        unless football_team_builder.is_a?(FootballTeamBuilder)
            fail NoNewMethodError.new(“Cannot build with arguments that are “ +
                “not FootballTeamBuilder class objects”)
        end
        football_team_builder.build_all
    end

end
 
Here’s our form and its form load event method.
 
def Form1_Load(sender, e)

      #new up a Director
      f = GoverningBody.new

      #new up a concrete builder
      soccer_builder = SoccerFootballTeamBuilder.new

      #go again a second time with another builder
      aussie_rules_builder = AustralianRulesFootballTeamBuilder.new

      #go again a second time with another builder
      rugby_league_builder = RugbyLeagueFootballTeamBuilder.new

      #pass the bulders build to the Director
      f.build_football_team(soccer_builder)
      f.build_football_team(aussie_rules_builder)
      f.build_football_team(rugby_league_builder)

      #store the teams and details in arrays
      @team1 = [soccer_builder.footy_team?.team_type_name?,
        soccer_builder.print_team_details]
      @team2 = [aussie_rules_builder.footy_team?.team_type_name?,
        aussie_rules_builder.print_team_details]
      @team3 = [rugby_league_builder.footy_team?.team_type_name?,
        rugby_league_builder.print_team_details]

      self.listBox1.Items.Add(@team1[0])
      self.listBox1.Items.Add(@team2[0])
      self.listBox1.Items.Add(@team3[0])

end
ironruby_builder_ui
ironruby_builder_ide Used in concert with a Windows::Forms application (with some help from Ruby In Steel) we can build the following user interface to demonstrate our Builder(s) in action. The entire code can be found here and includes all the code and presentations from previous episodes in the series. Next in the series is the last of the creational patterns, the Prototype pattern.

Share/Save/Bookmark

Preparing for IronRuby

October 7th, 2008 Simon Segal No comments

I decided to share my experiences on the path to IronRuby so far and perhaps it might be useful to others who wish to travel that road.

Not so long ago I posted about choices in front of me regarding learning a new language. After having programmed in C# for some 7 or so years I wasn’t going to choose another statically typed language, I wanted to add a dynamic language to my arsenal and with the DLR on it’s way and a key interest and stake in the Silverlight, the choice as obvious.

After having decided to dedicate the time and effort to IronRuby, the next question was how to address the learning. Clearly picking up IronRuby as the first pit stop was going to come with some difficulties borne out of the fact that the documentation isn’t great yet and the toolset way of being close. Based on this, I decided that learning Ruby first was the best way to progress this goal for two main reasons, one it allowed me to learn in the comfort of an IDE (NetBeans) to write ‘do as you learn‘ code and also gave me a perspective on IronRuby that is not indifferent to its genealogy.

So after downloading NetBeans (Ruby Edition) and installing Ruby 1.8.6, I got my hands on the excellent free online book by Jeremy McAnally, the title of which is “Mr Neighbourly’s Humble Little Ruby Book“. This book is a nice little quick starter to get you comfortable with the absolute basics of Ruby, but needs to be followed by something with a bit more industrial strength such as Matz very own offering The Ruby Programming Language.

DLR PadOnce having navigated this far, I decided that it was time to pull down the IronRuby bits and start to have a play. A while back now, Hanselman and Gu both posted some early pieces on getting started with IronRuby. Most people seem intent on making XAML based applications the focus of their IronRuby attention, which in turn lead me to DLR Pad (see the image above) which provides the ability to interactively script IronRuby (and IronPython) against a statically set window that contains a XAML UI layout (interesting). From there I found my way to Ivan Porto Carerro’s blog and book on IronRuby. Ivan’s book is not yet released but is available as early access, so I decided to avail myself of it.

And if your wondering what code looks like (see below) for something that you might have been routinely doing (as I was), it doesn’t take long to knock something (trivial in this case) together to begin to get the picture, in the case of having gone down the path I described above.

require ‘mscorlib’
require ‘System.Windows.Forms,
  Version=2.0.0.0, Culture=neutral,
  PublicKeyToken=b77a5c561934e089′

begin

    #alias the forms namespace
    Windows = System::Windows::Forms
    #new up a form & set it’s text
    first_ruby_window = Windows::Form.new
    first_ruby_window.Text = “Simons first Ruby Form”
    #new up a button
    first_ruby_button = Windows::Button.new
    #subscribe to the buttons click event
    first_ruby_button.click {|sender, args| first_ruby_button.Text =
                                    “I got clicked!”}
    #add the button to the form
    first_ruby_window.Controls.Add(first_ruby_button)
    #show my new form
    first_ruby_window.ShowDialog()

end

And we get the following:

first_ruby_form

So that’s my story (to date) and perhaps it offers some help in getting you underway with your IronRuby / DLR journey.

Share/Save/Bookmark

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia