概要
Factory Pattern 〜 CodeIQの参加者を生成する
詳細
Factory Patternは、インスタンス生成をサブクラスに任せるパターン。
Creatorにインスタンス生成の手順を受け持ち、
Creatorを継承したサブクラスがインスタンスの生成を受け持つ。
実装内容はTemplate Methodパターンと同じ。
サンプル1 仕様
CodeIQへの参加を実装します。
出題者、解答者が参加します。
出題者、解答者はそれぞれ名前を持ちます。
Factoryパターン上の役割は以下になります
ParticipationFactory => Creator
ProblemMasterFactory => ConcreteCreator
SolverFactory => ConcreteCreator
Participation(具体的に定義はせずparticipateメソッドでダックタイピング) => Product
ProblemMaster => ConcreteProduct
Solver => ConcreteProduct
サンプル1 コード
class ParticipationFactory def initialize(persons) @persons = [] persons.each do |name| @persons << new_person(name) end end def participate @persons.each { |person|puts person.participate } end end class ProblemMaster def initialize(name) @name = name end def participate "#{@name}はCodeIQに出題者として参加してます" end end class ProblemMasterFactory < ParticipationFactory def new_person(name) ProblemMaster.new(name) end end class Solver def initialize(name) @name = name end def participate "#{@name}はCodeIQに解答者として参加してます" end end class SolverFactory < ParticipationFactory def new_person(name) Solver.new(name) end end pmf = ProblemMasterFactory.new(['tanaka', 'sato']) pmf.participate pmf = SolverFactory.new(['suzuki', 'honda']) pmf.participate
出力
tanakaはCodeIQに出題者として参加してます satoはCodeIQに出題者として参加してます suzukiはCodeIQに解答者として参加してます hondaはCodeIQに解答者として参加してます
サンプル2 仕様
基本仕様はサンプル1と同じ。
サンプル1は各クラスごとにFactoryクラスを作成するのですが、
ProductとFactoryを常にセットで作成する必要があり、もう少し効率化したいです。
そこで、CreatorであるParticipationFactoryに生成対象のクラスも一緒に渡すことにします。
これによってConcreteFactoryは不要になりました。
サンプル2 コード
require 'tbpgr_utils' class ParticipationFactory def initialize(persons, classes) @persons = [] [persons, classes].together { |name, klass|@persons << klass.new(name) } end def participate @persons.each { |person|puts person.participate } end end class ProblemMaster def initialize(name) @name = name end def participate "#{@name}はCodeIQに出題者として参加してます" end end class Solver def initialize(name) @name = name end def participate "#{@name}はCodeIQに解答者として参加してます" end end pmf = ParticipationFactory.new( ['tanaka', 'sato', 'suzuki', 'honda'], [ProblemMaster, ProblemMaster, Solver, Solver] ) pmf.participate __END__ togetherはtbpgr_utils gemの機能です。 複数のリストを同時にイテレートします。 詳しくは下記参照。 https://github.com/tbpgr/tbpgr_utils
出力
tanakaはCodeIQに出題者として参加してます satoはCodeIQに出題者として参加してます suzukiはCodeIQに解答者として参加してます hondaはCodeIQに解答者として参加してます