2
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?

More than 3 years have passed since last update.

複雑な計算があるならCalcRuleクラスを作ろう

Posted at

計算処理があると関連するActiveRecordモデルにメソッドを作りますよね1

product.rb
class Product < ApplicationRecord
  def billing_price
    price * consumption_tax_rate
  end

  def consumption_tax_rate
    # 消費税率を返す
  end
end

税込金額を計算するぐらいなら、そこまで問題を感じません。ただ、キャンペーンで値引きするようになったり、値引き条件が複雑になってくると、商品クラスが金額計算クラスのように思えてきます。

product.rb
class Product < ApplicationRecord
  def billing_price
    campaign_discounted_price * consumption_tax_rate
  end

  def consumption_tax_rate
    # 消費税率を返す
  end

  def campaign_discounted_price
    # キャンペーンを適用した値段を返す
    # キャンペーンが複雑になるとこのメソッドが複雑になったり、
    # このメソッドからしか呼ばれないメソッドが増えていってしまう!
  end
end

このままではFat Modelになってしまいます。

計算のためのクラスを作ろう

消費税の計算をするクラスとキャンペーン値引きの計算をするクラスを作ります。

consumption_tax_calc_rule.rb
class ConsumptionTaxCalcRule
  attr_accessor :price, :product_type
  # product_typeは軽減税率を適用するか判断する情報(ということにしておいてください)
  def initialize(price, product_type)
    self.price = price
    self.product_type = product_type
  end

  def tax_included_price
    price * tax_rate
  end

  def tax_rate
    # 消費税率を返す
  end
end
campaign_discount_calc_rule.rb
class CampaignDiscountCalcRule
  attr_accessor :price, :campaigns
  # campaignsはキャンペーン値引きのための情報(ということにしておいてください)
  def initialize(price, campaigns)
    self.price = price
    self.campaigns = campaigns
  end

  def discounted_price
    # このメソッドからしか呼ばれないメソッドが増えても、
    # キャンペーン値引き計算クラスに
    # キャンペーン値引きのためのメソッドが増えるだけだから何もおかしくない!
  end
end

商品クラスは、CalcRuleクラスを使うだけです。

product.rb
class Product < ApplicationRecord
  def billing_price
    discount_rule = CampaignDiscountCalcRule.new(price, campaigns)
    tax_rule = ConsumptionTaxCalcRule.new(discount_rule.discounted_price, product_type)
    tax_rule.tax_included_price
  end
end

これで、消費税が変わったり、キャンペーンが変更になってもCalcRuleクラスだけ確認すればよくなりました!


このエントリは要求分析駆動設計ビジネスルールの計算について具体例を示し汎用的な内容に書き換えたものです。
めっちゃ長いけど、RailsでDDDっぽいことする話です。

  1. 本題ではないので省略してるけど、浮動小数点数の計算はちゃんとやろう!=>[Ruby]消費税計算にはBigDecimalを使いましょう

2
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
2
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?