Sistema Bancário
Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 63 de 65.
Desafio
DifícilCrie um banco com dois tipos de contas. Cada operação retorna um dicionário de resultado {"ok": bool, "message": String}; o código fornecido o imprime como OK: MESSAGE ou Failed: MESSAGE. Todos os valores são float e cada valor em uma mensagem tem duas casas decimais após um $.
Transaction em transaction.gd: o construtor recebe kind ("deposit", "withdrawal" ou "interest") e amount. _to_string() retorna o tipo com a primeira letra maiúscula, seguido do valor: Deposit - $200.00. Uma transação não armazena sua conta.
Account em account.gd é uma classe @abstract:
- O construtor recebe
account_number,owner_nameeinitial_balance. O dinheiro fica em_balance, que é privado;balanceé uma propriedade somente de leitura cujo getter retorna_balance._historyé umArray[Transaction], eget_history()o retorna. - Dois métodos abstratos:
account_type() -> Stringewithdrawal_error(amount: float) -> String, que retorna o motivo pelo qual um saque é recusado, ou"". deposit(amount): um valor de0ou menos falha comDeposit amount must be positive. Caso contrário, adiciona o dinheiro, registra uma transaçãodeposite retornaDeposited $A. New balance: $B.withdraw(amount): um valor de0ou menos falha comWithdrawal amount must be positive; umwithdrawal_error()não vazio falha com esse texto. Caso contrário, retira o dinheiro, registra umwithdrawale retornaWithdrew $A. New balance: $B, seguido de(Overdraft)quando o saldo fica abaixo de0._to_string()retornaTYPE NUMBER (OWNER): $BALANCE.
SavingsAccount em savings_account.gd estende Account, com as constantes INTEREST_RATE = 0.02 e MIN_BALANCE = 100.0. Seu tipo é Savings. Um saque que deixaria menos que MIN_BALANCE é recusado com Cannot withdraw below minimum balance of $100.00. apply_interest() adiciona balance * INTEREST_RATE, registra uma transação interest e retorna Applied interest: $I. New balance: $B.
CheckingAccount em checking_account.gd estende Account, com a constante OVERDRAFT_LIMIT = 200.0. Seu tipo é Checking. O saldo pode chegar a -200.00; um saque que o deixaria abaixo desse valor é recusado com Cannot exceed overdraft limit of $200.00.
Bank em bank.gd mantém as contas em um dicionário privado indexado pelo número da conta:
- O construtor recebe
bank_name. create_account(kind, account_number, owner_name, initial_balance)é uma fábrica:kindpode sersavingsouchecking, independentemente de maiúsculas e minúsculas. Falha comAccount number already existsouInvalid account typee, caso contrário, retornaSavings account created successfully(ouChecking).get_account(account_number) -> Accountretorna a conta ounull.transfer(from_number, to_number, amount): falha comOne or both accounts not found; faz um saque da primeira conta e, se ele falhar, retorna uma falha comTransfer failed:seguido da mensagem do saque. Caso contrário, deposita na segunda conta e retornaTransferred $A from FROM to TO.total_holdings() -> floatretorna a soma de todos os saldos.
O código fornecido lê o nome do banco e, em seguida, os comandos. Para esta entrada:
First Bank
open savings|S1|Alice|1000
open checking|C1|Bob|50
withdraw S1|950
transfer S1|C1|300
withdraw C1|400
history C1
totala saída é:
OK: Savings account created successfully
OK: Checking account created successfully
Failed: Cannot withdraw below minimum balance of $100.00
OK: Transferred $300.00 from S1 to C1
OK: Withdrew $400.00. New balance: $-50.00 (Overdraft)
History of C1:
1. Deposit - $300.00
2. Withdrawal - $400.00
Total held by First Bank: $650.00Seu código deve ficar em transaction.gd, account.gd, savings_account.gd, checking_account.gd e bank.gd. main.gd contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
extends Node
func _ready():
# Código de entrada/saída fornecido: mantenha-o como está
var bank := Bank.new(OS.read_string_from_stdin())
var line := OS.read_string_from_stdin()
while line != "":
var parts := line.split(" ", true, 1)
var f: PackedStringArray = parts[1].split("|") if parts.size() > 1 else PackedStringArray()
match parts[0]:
"open":
show_result(bank.create_account(f[0], f[1], f[2], float(f[3])))
"deposit":
show_result(bank.get_account(f[0]).deposit(float(f[1])))
"withdraw":
show_result(bank.get_account(f[0]).withdraw(float(f[1])))
"interest":
var account: Account = bank.get_account(f[0])
if account is SavingsAccount:
var savings := account as SavingsAccount
show_result(savings.apply_interest())
else:
print("Failed: ", f[0], " is not a savings account")
"transfer":
show_result(bank.transfer(f[0], f[1], float(f[2])))
"history":
var history: Array = bank.get_account(f[0]).get_history()
print("History of ", f[0], ":")
for i in history.size():
print(i + 1, ". ", history[i])
"account":
print(bank.get_account(f[0]))
"total":
print("Total held by %s: $%.2f" % [bank.bank_name, bank.total_holdings()])
line = OS.read_string_from_stdin()
func show_result(result: Dictionary) -> void:
print(("OK: " if result["ok"] else "Failed: ") + result["message"])
Todas as lições de Programação orientada a objetos
1Fundamentos da POO
Arquivos externosIntrodução à POOClasses vs. objetosA palavra-chave selfMétodosPropriedadesConstrutor (_init)Revisão - Calculadora simples4Polimorfismo
Revisitando a Sobrescrita de MétodosDuck TypingClasses e Métodos AbstratosDesign de InterfacesRevisão - Calculadora de Formas7Sinais
O que é um sinal?Declarando e emitindoConectando-se a sinaisSinais com argumentosRevisão - Sistema de saúde10Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite2Propriedades de Classe
Variáveis de Instância vs. EstáticasFunções EstáticasMétodos Setters de PropriedadeMétodos Getters de PropriedadePrivado por ConvençãoRecapitulando: Gerenciador de Conta Bancária5Encapsulamento
Membros públicos e privadosValidação com settersOcultação de informaçõesPropriedades somente para leituraRevisão - Sistema de registros de alunos8Conceitos Avançados de POO
Composição vs. HerançaClasses InternasNós como ComponentesRefCounted vs. NodeEnums em Classes3Herança
Herança básicaA palavra-chave superSobrescrita de métodosCadeias de herançaVerificações de tipo com isRevisão - Hierarquia de funcionários6Métodos especiais
Introdução aos métodos virtuaisO método _to_stringIteradores personalizadosRevisão - Lista personalizada9Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy12Desafios Finais
Plataforma de Ensino OnlineSistema BancárioDesenvolvimento de Personagens de JogosServiço de Aluguel de VeículosPratique por conta própria: Compilador de GDScript online