Как я могу точно передать отдельных пользователей и учетные записи в хэш, а затем убедиться, что отдельные остатки на счетах не складываются вместе в один?

Работаем над банковской программой. Мне нужно убедиться, что пользователи (объекты-личности) имеют свои собственные банковские счета, которые они могут создавать с разными балансами в каждой учетной записи, с которой они могут взаимодействовать. Они должны иметь возможность вносить, снимать, переводить деньги и т. Д. У меня возникают проблемы с выводом корректно.

Как вы увидите, когда он говорит, сколько денег имеет каждый человек на своем аккаунте, который вызывается, он отображает сумму по всем аккаунтам, созданным этим пользователем. Любые идеи о том, как я могу это исправить?

Кроме того, мне нужно небольшое руководство по оператору 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 ответ

Я думаю, что некоторые проблемы могут быть связаны с неправильным пониманием объектно-ориентированного проектирования, а не конкретно с Ruby. Итак, давайте уточним банк:

Банка

  • open(name, balance) Откройте счет с указанным именем и балансом. Вернуть аккаунт в deposit, withdraw а также transfer от.
  • deposit(amount) кредитует баланс банка.
  • withdraw(amount) дебетует баланс банка (если у них достаточно денег).

И тогда из этого мы видим, что нам также нужно Account класс, но мы будем создавать экземпляры этого изнутри Bank#open и мы не хотим, чтобы люди могли создавать экземпляры любым другим способом, поэтому мы будем скрывать этот класс внутри Bank:

Банковский счет

  • deposit(amount) кредитует остаток на счете и в банке.
  • withdraw(amount) дебетует баланс аккаунта и пользователя (если у них достаточно денег).
  • transfer(amount, account) переводы с одного счета на другой, если необходимые средства имеются.

Теперь мы заметили, что Bank а также Bank::Account делятся некоторыми методами, а именно deposit, а также withdrawи, кроме того, некоторое состояние (баланс и название объекта, например, "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 Класс отслеживает все свои учетные записи, и при запросе баланса он просто суммирует остатки всех своих учетных записей.

Вероятно, я бы выбрал позднее, потому что это уменьшает сцепление, но это дизайнерское решение, которое нужно принимать, когда этого требует набор функций программы.

Другие вопросы по тегам