Как я могу точно передать отдельных пользователей и учетные записи в хэш, а затем убедиться, что отдельные остатки на счетах не складываются вместе в один?
Работаем над банковской программой. Мне нужно убедиться, что пользователи (объекты-личности) имеют свои собственные банковские счета, которые они могут создавать с разными балансами в каждой учетной записи, с которой они могут взаимодействовать. Они должны иметь возможность вносить, снимать, переводить деньги и т. Д. У меня возникают проблемы с выводом корректно.
Как вы увидите, когда он говорит, сколько денег имеет каждый человек на своем аккаунте, который вызывается, он отображает сумму по всем аккаунтам, созданным этим пользователем. Любые идеи о том, как я могу это исправить?
Кроме того, мне нужно небольшое руководство по оператору 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
Класс отслеживает все свои учетные записи, и при запросе баланса он просто суммирует остатки всех своих учетных записей.
Вероятно, я бы выбрал позднее, потому что это уменьшает сцепление, но это дизайнерское решение, которое нужно принимать, когда этого требует набор функций программы.