如何准确地将单个用户和帐户推送到哈希值,然后确保单独的帐户余额不会一起添加?

时间:2014-06-01 20:31:31

标签: arrays ruby hash accounts

参与银行计划。我需要确保用户(人物对象)拥有自己的银行帐户,他们可以在每个帐户中使用不同的余额创建他们可以与之交互的帐户。他们应该能够存款,取款,转账等。我在输出时遇到了问题。

正如您将看到的,当它显示每个人在其帐户中有多少钱被调用时,它会显示该用户创建的所有帐户的总数。关于如何解决这个问题的任何想法?

另外,我需要对我的传输方法中的if语句提供一些指导。我不能让它为每种情况正确显示。

class Bank

  attr_accessor :balance, :withdrawal, :deposit, :transfer, :users
  @@accounts = {}
  #@@balance = {}
  def initialize(bname)
    @bname = bname
    @users = {}
    @@accounts[users] = bname
    #@@balance[users] = bname
    puts "#{@bname} bank was just created."
  end

  def open_account(name, bname, balance = 0)
    if @users.include?(name)
      bname.each do |users|
        @@accounts.push('users')
      end
    end
    @balance = balance
    puts "#{name}, thanks for opening an account at #{@bname} with an initial $#{balance} deposit!"
  end

  def user
    @users
  end

  def withdrawal(name, amount)
    @balance -= amount
    puts "#{name} withdrew $#{amount} from #{@bname}.  #{name} has #{@balance}.  #{name}'s account has #{@balance}."
  end

  def deposit(name, amount)
    @balance += amount
    puts "#{name} deposited $#{amount} to #{@bname}.  #{name} has #{@balance}.  #{name}'s account has #{@balance}."
  end

  def transfer(name, account2, amount)
    if name == name
      @balance -= amount
      @transfer = amount
      puts "#{name} transfered $#{amount} from #{@bname} account to #{account2} account.  The #{@bname} account has $#{amount} and the #{account2} account has $#{@balance}."
    else
      puts "That account doesn't exist."
    end
  end
end

class Person

  attr_accessor :name, :cash
  def initialize(name, cash = 100)
    @name = name
    @cash = cash
    puts "Hi, #{name}.  You have $#{cash} on hand!"
  end
end

chase = Bank.new("JP Morgan Chase")
wells_fargo = Bank.new("Wells Fargo")
randy = Person.new("Randy", 1000)
kristen = Person.new("Kristen", 5000)
justin = Person.new("Justin", 1500)
chase.open_account('Randy', "JP Morgan Chase", 200)
chase.open_account('Kristen', "JP Morgan Chase", 300)
chase.open_account('Justin', "JP Morgan Chase", 400)
wells_fargo.open_account('Randy', "Wells Fargo", 200)
wells_fargo.open_account('Kristen', "Wells Fargo", 300)
chase.deposit("Randy", 200)
chase.deposit("Kristen", 350)
chase.withdrawal("Kristen", 500)
chase.transfer("Randy", "Wells fargo", 100)
chase.deposit("Randy", 150)

此代码的当前输出是:

JP Morgan Chase bank was just created.
Wells Fargo bank was just created.
Hi, Randy.  You have $1000 on hand!
Hi, Kristen.  You have $5000 on hand!
Hi, Justin.  You have $1500 on hand!
Randy, thanks for opening an account at JP Morgan Chase with an initial $200 deposit!
Kristen, thanks for opening an account at JP Morgan Chase with an initial $300 deposit!
Justin, thanks for opening an account at JP Morgan Chase with an initial $400 deposit!
Randy, thanks for opening an account at Wells Fargo with an initial $200 deposit!
Kristen, thanks for opening an account at Wells Fargo with an initial $300 deposit!
Randy deposited $200 to JP Morgan Chase.  Randy has 600.  Randy's account has 600.
Kristen deposited $350 to JP Morgan Chase.  Kristen has 950.  Kristen's account has 950.
Kristen withdrew $500 from JP Morgan Chase.  Kristen has 450.  Kristen's account has 450.
Randy transfered $100 from JP Morgan Chase account to Wells fargo account.  The JP Morgan Chase account has $100 and the Wells fargo account has $350.
Randy deposited $150 to JP Morgan Chase.  Randy has 500.  Randy's account has 500.

1 个答案:

答案 0 :(得分:0)

我认为有些问题可能归结为对面向对象设计的误解,而不是对Ruby的误解。所以,让我们指定银行:

  

银行

     
      
  • open(name, balance)开设一个名称和余额的帐户。将帐户退回到depositwithdrawtransfer
  •   
  • deposit(amount)归功于银行的余额。
  •   
  • withdraw(amount)扣除银行余额(如果他们有足够的钱)。
  •   

然后我们发现我们还需要一个Account课程,但是,我们会在Bank#open内部创建它的实例,我们不希望别人能够以任何其他方式创建实例,因此我们将此类隐藏在Bank内:

  

银行::帐户

     
      
  • deposit(amount)也会记入帐户和银行的余额。
  •   
  • withdraw(amount)借记帐户和用户的余额(如果他们有足够的钱)。
  •   如果所需资金可用,则
  • transfer(amount, account)从一个帐户转帐到另一个帐户。
  •   

现在我们注意到BankBank::Account正在分享一些方法,即depositwithdraw,另外还有一些州,(余额和名称)实体,例如银行的"JP Morgan Chase"或某人的"Joe Bloggs"。所以,让我们把它抽象到自己的课堂上,(我称之为BalanceHolder,但它并不重要,只要它有意义。)

把它放在一起,我们得到了这个:

class BalanceHolder
  attr_reader :name, :balance
  def initialize(name, balance)
    @name    = name
    @balance = balance
  end

  def deposit(amount)
    @balance += amount
  end

  def withdraw(amount)
    raise ArgumentError, "#{@name} has insufficient funds." if @balance < amount
    @balance -= amount
  end
end

class Bank < BalanceHolder
  def open(name, balance)
    deposit(balance)
    Bank::Account.new(self, name, balance)
  end

  private
  class Account < BalanceHolder
    def initialize(bank, name, balance)
      @bank = bank
      super(name, balance)
    end

    def deposit(amount)
      super
      @bank.deposit(amount)
    end

    def withdraw(amount)
      super
      @bank.withdraw(amount)
    end

    def transfer(amount, account)
      withdraw(amount)
      account.deposit(amount)
    end
  end
end

chase       = Bank.new("JP Morgan Chase", 0)
wells_fargo = Bank.new("Wells Fargo", 0)

randy_chase = chase.open("Randy", 200)
randy_wells = wells_fargo.open("Randy", 200)

randy_chase.deposit(200)
randy_chase.transfer(100, randy_wells)

我所写的内容和你所写的内容之间最重要的区别可能是关注点分离(类似的想法是单一责任原则,或 SRP )。这是指在我的界面中,如果你想将钱存入账户,你可以在账户上调用方法,(而不是在银行上调用方法,将账户名称作为参数),以及为了解决这个问题,每个帐户都知道它属于哪个银行(因为这是特定帐户状态的一部分)。

另外值得注意的是,银行在开立账户后无法对账户进行任何操作,因此银行无需了解与之相关的所有账户。

你在我的模型中有一件事我没有加入我的想法,一个人可以在不同的银行拥有多个账户。如果我这样做,有几种方法可以解决它。所有这些都涉及创建另一个名为Person的类,它处理特定人的平衡和名称。

  • 一种方法是将Person作为BalanceHolder的子类,让Account更新其关联人员与每笔交易的余额。
  • 或者,我可以让Person班级跟踪其所有帐户,并且在请求余额时,它只是汇总其所有帐户的余额。

我可能会选择后者,因为它会减少耦合,但这是在程序的功能集需要时做出的设计决定。