0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Strategyパターン・Factoryパターン試してみた

Posted at

『オブジェクト指向実践ガイド』を読み、Strategyパターン・Factoryパターンを利用することで、拡張性・保守性が向上することを学んだ。

既存システムでStrategyパターンを利用している箇所があったが、本書で書かれていたものと比較するともう少し改善できそうな点があった。
どのように改善できそうか試してみる。

既存コード例(before)

現状だと以下のような問題を抱えています。

  • 新しい仕様が追加されるたびにstrategyメソッドを修正する必要がある(Open/Closed原則違反)
  • Strategizableモジュールが複数の仕様の知識を持っている(単一責任原則違反)
  • 各仕様に関連するクラス群への直接的な依存(依存関係の問題)
  • 全ての分岐をテストする必要がある(
    テストの複雑さ)

↓のような感じのmoduleが定義されており、Hogeモデルにincludeして、hoge.strategyのように呼び出しています。

module Hoge::Strategizable
  extend ActiveSupport::Concern
  Strategy = Data.define(
    :updater,
    :error_checker,
    :exporter
  )

  def strategy
    case hoge_hoge_id
    when 1
      Strategy.new(
        updater: Hoge::Updater::Fuga1,
        error_checker: Hoge::ErrorChecker::Fuga1,
        exporter: Hoge::Exporter::Fuga1,
      )
    when 2
      # ... 略
    when 3
      # ... 略
    end
  end
end

Strategyパターン/ Factoryパターン(after)

StrategyパターンとFactoryパターンを利用しても呼び出しはhoge.strategyのままでよく、以下のメリットを得られるように変更することができました。

  • 各Strategyクラスを独立してテストできる(
    テストしやすい)
  • 新しい仕様の追加が容易(拡張性)
  • 各仕様の変更が他に影響しない(保守性)
module Hoge::Strategizable
  extend ActiveSupport::Concern
  Strategy = Data.define(
    :updater,
    :error_checker,
    :exporter
  )

  def strategy
    Hoge::Strategy::Base.for(hoge_hoge_id)
  end
end
# app/models/hoge/strategy/base.rb
module Hoge::Strategy
  class Base
    def self.for(hoge_hoge_id)
      case hoge_hoge_id
      when 1 then Fuga1.new
      when 2 then Fuga2.new
      when 3 then Fuga3.new
      else raise "Unknown specification: #{hoge_hoge_id}"
      end
    end

    def updater; raise NotImplementedError; end
    def error_checker; raise NotImplementedError; end
    def exporter; raise NotImplementedError; end
  end
end

# app/models/hoge/strategy/fuga1.rb
class Hoge::Strategy::Fuga1 < Hoge::Strategy::Base
  def updater
    Hoge::Updater::Fuga1
  end

  def error_checker
    Hoge::ErrorChecker::Fuga1
  end

  def exporter
    Hoge::Exporter::Fuga1
  end
end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?