如何摆脱所有功能中的类似论点

时间:2015-07-21 22:41:04

标签: ruby-on-rails ruby oop refactoring

这是处理汇款的有效记录类。

class Wallet < ActiveRecord::Base
  belongs_to :user
  has_many :deposits, dependent: :destroy
  has_many :deposit_requests, dependent: :destroy
  has_many :withdrawals, dependent: :destroy
  has_many :withdrawal_requests, dependent: :destroy

  def deposit_with_tax_deduction! amount
    deposit! amount
    deduct_tax(amount)
  end

  def deposit! amount
    deposits.create! amount: amount - tax_for(amount)
  end

  def withdraw! amount
    if can_spend? amount
      withdrawals.create! amount: amount 
    else
      raise "Недостаточно средств"
    end
  end

  def total
    deposits.sum(:amount) - withdrawals.sum(:amount) + deposit_requests.success.sum(:amount) - withdrawal_requests.success.sum(:amount)
  end

  def can_spend? amount
    total - amount > 0
  end

  def tax_for(amount)
    amount.to_f * Option.current.tax / 100
  end

  private
  def deduct_tax(amount)
    AdminWallet.deposit! amount
  end
end

我几乎在课堂上的每个方法中都有相同的参数(amount)。它是一种代码味道,经过多年可能导致不良后果吗?我应该遵循什么模式?

2 个答案:

答案 0 :(得分:2)

很好。

实例变量通常被视为对象的状态。在你的情况下,“金额”变量将是一个不必要的状态变异,因为它除了当前执行之外没有任何重要性。

但是,我必须提到这里没有严格的规定。这在很大程度上取决于你班级的性质。通常我们区分数据对象行为对象。前者通常更持久,而后者在其使用中更具可配置性。因此,“状态”一词在每个词中都有不同的含义。

目前,正如“Wallet”类名所示,您有一个数据对象。稍后,您可以重构代码并创建“Transaction”类。在这种类中,将设置量作为实例变量更有意义。您甚至可以轻松地使用命令模式来撤消操作。

顺便说一下,传递夸大的参数是代码气味,这意味着你应该考虑将你的代码分成更多的类。请记住:不要试图解决几年后可能遇到的问题。关注你现在遇到的问题。

答案 1 :(得分:0)

您可以将金额定义为instance variable,因为您的方法也是instance methods

所以

class Wallet < ActiveRecord::Base
  ...
  attr_accessor :amount

  def tax_for
  end
  ...
end

你可以按(ex)

使用它
wallet = Wallet.new
wallet.amount = 100
wallet.tax_for