概要
GoFのデザインパターンのTemplateメソッドパターンとFactoryメソッドパターンについて。
FactoryメソッドパターンはTemplateメソッドパターンを利用しているので
Factoryメソッドパターンのサンプル説明を持って、Templateメソッドパターンの説明を兼ねることにします。
Templateメソッドパターン
内容
処理の流れをAbstractの基底クラスで行い、具体的な処理を継承側で行う。
大筋の処理が同じで、個別の処理が異なるサブクラスを多数作成する際などに有効。
登場人物
AbstractClass = テンプレート部分を定義する抽象クラス
ConcreteClass = 個別の実装を受け持つ継承クラス
Factoryメソッドパターン
インスタンスの生成を工場=Factoryに任せるパターン。
クラスの生成を隠蔽することで結合度を下げることができます。
登場人物
AbstractFactoryClass = Factoryの共通したテンプレートを定義する抽象クラス
ConcreteFactoryClass = Factoryの個別実装を受け持つ継承クラス
AbstractProduct = Productのインターフェースとテンプレートを定義する抽象クラス
ConcreteProduct = Productの個別実装を受け持つ
サンプル仕様
AbstractFactoryClass役 = TagFactory:HTMLのタグを生成する
ConcreteFactoryClass = DivTagFactory:HTMLのDIVタグを生成する
ConcreteFactoryClass = SpanTagFactory:HTMLのSPANタグを生成する
AbstractProduct = Tag:インターフェースとテンプレートを定義する抽象クラス
ConcreteProduct = Div:Divタグ個別実装を受け持つ
ConcreteProduct = Span:SpanTagの個別実装を受け持つ
main = 動作確認用メイン処理
サンプルコード
tag_factory.rb
# encoding: Shift_JIS require_relative './tag' =begin rdoc = Tagを生成するFactoryクラス =end class TagFactory @tag protected def setTag() raise 'error' end public def getTag() setTag return @tag end end
div_tag_factory.rb
# encoding: Shift_JIS require_relative './tag_factory' require_relative './tag' require_relative './div' =begin rdoc = DivTagを生成するFactoryクラス =end class DivTagFactory < TagFactory protected def setTag() @tag = Div.new end end
span_tag_factory.rb
# encoding: Shift_JIS require_relative './tag_factory' require_relative './tag' require_relative './span' =begin rdoc = SpanTagを生成するFactoryクラス =end class SpanTagFactory < TagFactory protected def setTag() @tag = Span.new end end
tag.rb
# encoding: Shift_JIS =begin rdoc = Tagクラス =end class Tag @tag_name = "" attr_accessor :inner_text protected def setTag() raise 'error' end public def getOuterHtml() setTag return "<#{@tag_name}>#{@inner_text}</#{@tag_name}>" end end
div.rb
# encoding: Shift_JIS require_relative './tag' =begin rdoc = Divクラス =end class Div < Tag protected def setTag() @tag_name = "div" end end
span.rb
# encoding: Shift_JIS require_relative './tag' =begin rdoc = Spanクラス =end class Span < Tag protected def setTag() @tag_name = "span" end end
main.rb
require_relative './tag_factory' require_relative './div_tag_factory' require_relative './span_tag_factory' require_relative './tag' require_relative './div' require_relative './span' div_factory = DivTagFactory.new div = div_factory.getTag div.inner_text = "divの中身" puts div.getOuterHtml span_factory = SpanTagFactory.new span = span_factory.getTag span.inner_text = "spanの中身" puts span.getOuterHtml
出力
<div>divの中身</div> <span>spanの中身</span>