04 September 2012

Provides an interface for creating families of related or dependent objects without specifying their concrete classes.

This design pattern will be useful building attributes of the different types of heroes we will need. All the files can be downloaded.

Abstract Factory Pattern

As I have mentioned before Ruby doesn’t need to define the abstract classes or the interfaces. I defined different classes for the various hero attributes. This isn’t necessary with Ruby but it made the use of the Abstract Factory Pattern in the code more obvious.

Abstract-Factory-Pattern.rb
class Skill
  attr_accessor :description
  def initialize(description)
    @description = description
  end
end

class Feat
  attr_accessor :description
  def initialize(description)
    @description = description
  end
end

class Race
  attr_accessor :description
  def initialize(description)
    @description = description
  end
end

class Talent
  attr_accessor :description
  def initialize(description)
    @description = description
  end
end

class Power
  attr_accessor :description
  def initialize(description)
    @description = description
  end
end

class BodyType
  attr_accessor :description
  def initialize(description)
    @description = description
  end
end

class FantasyHeroAttributes
  def create_skill()
    Skill.new("I can build catupults!")
  end

  def create_feat()
    Feat.new("I can dodge arrows!")
  end

  def create_race()
    Race.new("I am an elf.")
  end

end

class SuperHeroAttributes
  def create_talent()
    Talent.new("I have in depth knowledge of guns and how to build them.")
  end

  def create_power()
    Power.new("I can fly!")
  end

  def create_body_type()
    BodyType.new("I am a robot.")
  end

end

module HandleAttributeFactory
  attr_accessor :attribute_factory_class, :attributes, :attribute_factory
  def initialize(attribute_factory_class)
    @attribute_factory_class = attribute_factory_class
    @attributes = Hash.new()
  end
end


class TechHero
  include HandleAttributeFactory

  def describe
    puts 'I am a technology based hero!'
    @attribute_factory = @attribute_factory_class.new()
    @attribute_factory_class.instance_methods(false).each { | the_method |
      @attributes[the_method.to_s] = @attribute_factory.send the_method
    }
    @attributes.each { | the_attribute |
      puts the_attribute[1].description
    }
  end
end


class HeroCreator
  def createHero(hero_type,attribute_factory=nil)
    @heroClass = self.class.const_get("#{hero_type}Hero")
    @heroClass.new(attribute_factory)
  end
end

creator = HeroCreator.new()


hero = creator.createHero('Tech',SuperHeroAttributes)
hero.describe

hero = creator.createHero('Tech',FantasyHeroAttributes)
hero.describe

Less Is More ~ Older posts are available in the archive.