概要
GoFのデザインパターンのFlyweightパターンについて。
再利用可能なインスタンスを保持しておくことで
処理の軽量化を図ることことを目的とするのがFlyweightパターンです。
Flyweightの語源はボクシングのフライ級。
ボクシングの階級の中でも軽量な階級であることから
処理の軽量化をイメージして名づけられています。
登場人物
Flyweight = 軽量化対象
FlyweightFactory = 軽量化対象の生成工場
Client = 利用者
実装サンプル
サンプル概要
HTMLを生成する処理を想定。
HTMLのタグを組み合わせて、HTML全体を出力します。
全く同じタグを使用する場合は、タグファクトリーによって
プールしてあるタグが利用されます。
登場人物
Flyweight = Tag : HTMLのタグ。軽量化対象役
FlyweightFactory = TagFactory : HTMLのタグを生成する工場。軽量化対象の生成工場役
Client = WebCreator : HTMLのタグを利用して、コンテンツを作る作成者。利用者役
サンプルコード
tag
# encoding: Shift_JIS =begin rdoc = Tagクラス =end class Tag attr_accessor :html def initialize(tag,attribute_map,has_close) @html="" if has_close @html << "<#{tag}" unless attribute_map.nil? attribute_map.each {|attribute_key,attribute_value| @html << " #{attribute_key}='#{attribute_value}'" } end @html << ">" @html << "$innerHtml" @html << "</#{tag}>" else @html << "<#{tag} />" end end end
tag_factory
# encoding: Shift_JIS require_relative './tag' =begin rdoc = TagFactoryクラス =end class TagFactory attr_accessor :tag_pool def initialize() @tag_pool = Hash.new end def create_tag(tag_name, attribute_map, has_close) tag = @tag_pool[tag_name] if tag.nil? tag = Tag.new(tag_name, attribute_map, has_close) tag_pool[tag_name] = tag else puts "reuse tag #{tag_name}" return tag end end end
web_creator
# encoding: Shift_JIS require_relative './tag' require_relative './tag_factory' =begin rdoc = WebCreatorクラス =end class WebCreator attr_accessor :tag_factory def initialize() @tag_factory = TagFactory.new end def create_tag(tag_name, attribute_map=nil, has_close=true) return @tag_factory.create_tag(tag_name, attribute_map, has_close) end end
main
# encoding: Shift_JIS require_relative './web_creator' web_creator = WebCreator.new html = web_creator.create_tag "html" head = web_creator.create_tag "head" body = web_creator.create_tag "body" DIV = "div" contents1 = Hash.new contents1[:id] = "contents" contents_tag1 = web_creator.create_tag(DIV,contents1) div1 = contents_tag1.html.sub('$innerHtml','div1') hr = web_creator.create_tag("hr",nil,false) contents2 = Hash.new contents_tag2 = web_creator.create_tag(DIV,contents1) div2 = contents_tag2.html.sub('$innerHtml','div2') inner_body = "#{div1}#{hr.html}#{div2}#{hr.html}" body_html = body.html.sub('$innerHtml',inner_body) head_html = head.html.sub('$innerHtml','') inner_html = "#{head_html}#{body_html}" puts html.html.sub('$innerHtml',inner_html)
出力結果
reuse tag div <html><head></head><body><div id='contents'>div1</div><hr /><div id='contents'>div2</div><hr /></body></html>