Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby | Decorator Pattern 〜 CodeIQの解答コメントをデコレーションする

概要

Decorator Pattern 〜 CodeIQの解答コメントをデコレーションする

詳細

Decorator Patternは、既存のオブジェクトに対して新たな機能をレイヤ状に追加していけるようにするパターンです。
これにより、一つのクラスやメソッドに責務の異なる様々な機能を詰め込んだり、
各責務の組み合わせ数分のサブクラスを作ったりすることを避けることができます。

サンプル仕様

CodeIQの解答時に出題者に提出するコメントを作成します。
コメントのパターンを用意しておいて組み合わせられるようにしておきます。

サンプルコード1は一つのクラスに全てのコメントパターンを実装しています。
サンプルコード2は各コメントパターンをモジュールで拡張できるようにしています。
また、サンプル2で拡張性が増したので文字列を囲むデコレータを追加しています。

サンプルコード1

require 'test_toolbox'

class AnswerComment
  module CommentMode
    THANKS = 1
    LOW_TENSION = 2
    HIGH_TENSION = 3
    SUGGESTIVE = 4
  end

  def comment(main_message, sub_message_types)
    messages = sub_message_types.reduce([]) do |messages, type|
      case type
      when CommentMode::THANKS
        messages << "楽しい問題をありがとうございます。"
      when CommentMode::LOW_TENSION
        messages << "ども。"
      when CommentMode::HIGH_TENSION
        messages << "ひゃっほーーう。いつもありがとーーーう!"
      when CommentMode::SUGGESTIVE
        messages << "問題文の3行目だけど・・・何でもないです。"
      end
    end
    messages << main_message
    messages
  end
end

ac = AnswerComment.new
puts ac.comment("簡単な問題でした。", [AnswerComment::CommentMode::THANKS, AnswerComment::CommentMode::HIGH_TENSION])
dp_line __LINE__
puts ac.comment("普通の問題でした。", [AnswerComment::CommentMode::THANKS, AnswerComment::CommentMode::LOW_TENSION, AnswerComment::CommentMode::SUGGESTIVE])

出力

楽しい問題をありがとうございます。
ひゃっほーーう。いつもありがとーーーう!
簡単な問題でした。
--------------------|filename=|line=31|--------------------
楽しい問題をありがとうございます。
ども。
問題文の3行目だけど・・・何でもないです。
普通の問題でした。

サンプルコード2

require 'test_toolbox'

class AnswerComment
  def comment(message)
    message
  end
end

module ThanksComment
  def comment(message)
    super("楽しい問題をありがとうございます。\n#{message}")
  end
end

module LowTensionComment
  def comment(message)
    super("ども。\n#{message}")
  end
end

module HighTensionComment
  def comment(message)
    super("ひゃっほーーう。いつもありがとーーーう!\n#{message}")
  end
end

module SuggestiveComment
  def comment(message)
    super("問題文の3行目だけど・・・何でもないです。\n#{message}")
  end
end

module SurroundComment
  def comment(message)
    super("★☆★☆★☆★☆★☆\n#{message}\n★☆★☆★☆★☆★☆\n")
  end
end

ac1 = AnswerComment.new
ac1.extend(HighTensionComment, ThanksComment)
puts ac1.comment("簡単な問題でした。")
dp_line __LINE__
ac2 = AnswerComment.new
ac2.extend(SuggestiveComment, LowTensionComment, ThanksComment, SurroundComment)
puts ac2.comment("普通の問題でした。")

出力

楽しい問題をありがとうございます。
ひゃっほーーう。いつもありがとーーーう!
簡単な問題でした。
--------------------|filename=|line=42|--------------------
★☆★☆★☆★☆★☆
楽しい問題をありがとうございます。
ども。
問題文の3行目だけど・・・何でもないです。
普通の問題でした。
★☆★☆★☆★☆★☆