Abstract Factory Pattern

Created: 4 September 2012  Modified:

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

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
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
tags:
   Less Is More