パンくず
内容
適用ケース要約
利用中のサーバクラスにメソッドを追加する必要があるが、そのクラスを変更できない
適用詳細
事情により、ソースコードを編集することが出来ないクラスに対して機能を追加したい場合、
クライアント側にサーバサーバクラスのインスタンスを第一引数にとるメソッドを追加します。
※あくまでJavaの書籍を基準にした内容なので、この前提で進めますがRubyの場合は
オープンクラスにより既存コードに影響を与えることなく処理を追加できます。
そのため、Javaのみで有効となるリファクタリング手法です。
サンプル
ある文章を「諸見里」語に変換します。
前提としてこのプログラムの作成者はStringクラスに諸見里語への翻訳機能を追加するのが妥当だと
思っています。
ここでの定義
諸見里語=「さ、す、せ、そ」が「しゃ、しゅ、しぇ、しょ」に変わる
しかし、JavaのStringクラスを変更することはできないため、自分のクラスに変換用のメソッドを追加します。
※諸見里については以下を参照
http://ja.wikipedia.org/wiki/%E8%AB%B8%E8%A6%8B%E9%87%8C%E5%A4%A7%E4%BB%8B
サンプルコード
▼リファクタリング前
class Moromizato def talk(message) moromizato_change_word_list={"さ"=>"しゃ","す"=>"しゅ","せ"=>"しぇ","そ"=>"しょ"} moromizato_message=message moromizato_change_word_list.each{|before,after| moromizato_message=moromizato_message.gsub(before,after) } return moromizato_message end end moromizato=Moromizato.new message="せたがやのさかな屋さんのそばにしらない人がいた。すごい。" puts "原文:#{message}" puts "諸見里:#{moromizato.talk(message)}"
▼リファクタリング後
class Moromizato def talk(message) return to_moromizato message end def to_moromizato(message) moromizato_change_word_list={"さ"=>"しゃ","す"=>"しゅ","せ"=>"しぇ","そ"=>"しょ"} moromizato_message=message moromizato_change_word_list.each{|before,after| moromizato_message=moromizato_message.gsub(before,after) } return moromizato_message end end moromizato=Moromizato.new message="せたがやのさかな屋さんのそばにしらない人がいた。すごい。" puts "原文:#{message}" puts "諸見里:#{moromizato.talk(message)}"
▼出力結果(共通)
原文:せたがやのさかな屋さんのそばにしらない人がいた。すごい。 諸見里:しぇたがやのしゃかな屋しゃんのしょばにしらない人がいた。しゅごい。
解説
諸見里語への変換機能をメソッドとして抽出したことで、
変換機能がクラス内で再利用可能となりました。
おまけ
RubyのオープンメソッドでStringクラスを拡張した場合。
あたかもStringクラスに組み込まれている機能であるかのように
諸見里語変換機能が利用できます。
class String def to_moromizato() moromizato_change_word_list={"さ"=>"しゃ","す"=>"しゅ","せ"=>"しぇ","そ"=>"しょ"} moromizato_message=self moromizato_change_word_list.each{|before,after| moromizato_message=moromizato_message.gsub(before,after) } return moromizato_message end end message="せたがやのさかな屋さんのそばにしらない人がいた。すごい。" puts "原文:#{message}" puts "諸見里:#{message.to_moromizato}"