演習 - 端末を使用した銀行口座のシミュレーション

PHPz
リリース: 2024-08-12 22:43:49
オリジナル
310 人が閲覧しました

理論から少し外れますが、ブートキャンプの次のステップは演習です (これをプロジェクト チャレンジと呼んでいます)。これまで取り上げた内容を統合するための実践的な部分を含めることは興味深いのではないかと考えました。

要求されたのは、支店番号口座番号顧客名、バランス。このデータは端末から取得する必要があり、最後に、アカウントが正常に作成されたことを示し、どのようなデータが入力されたかを示すメッセージが表示される必要があります。元の説明はここでご覧いただけます。

そうですね、それは非常に簡単なようです。しかし、私が受けたどんな仕事でもやりたいと思っていることの 1 つは、それを非常に短いステップに分割して、従うべき道を明確にすることです。これは、頭の中で流れを描いているときに、聞かれたことと意味が合っているかどうかが分かり、ダメだと思ったらすぐに方針を変更できるからでもあります。

Exercício - Simulando Uma Conta Bancária Através Do Terminal

したがって、従うべき手順は次のとおりです:

    端末で受信したデータとアカウント作成者メソッドを「格納」するクラスを作成します。
  1. ユーザーにデータを要求し、端末に入力された情報を読み取り、変数に保存します。
  2. 変数を読み取り可能な文字列に整理して、ユーザーに確認メッセージを表示します。
それほど複雑なものではないようです。ステップ 1 から始めて、次のものがあります:

ターミナルアカウント.java

public class TerminalAccount { // eu sei, sou muito criativo
    private int branch;
    private String account;
    private String clientName;
    private double balance;

    public void createAccount(){
        // aqui a mágica acontece
    }
}
ログイン後にコピー
このコースではアクセス修飾子についてはこれまであまり詳しく取り上げていませんが、銀行システムでは支店、口座、所有者、残高のデータは十分に保護され、クラスのみが保護される必要があることを想像して、すべてのフィールドをプライベートのままにすることにしました。それ自体がそれらにアクセスできる必要があります。

さらに、createAccount メソッドは何も返さず、コンソールにメッセージを表示するだけであるため、その戻り値は無効です。

このメソッドは、Java に関して私がイライラするいくつかの点の始まりです。ユーザーが入力したあらゆる種類の情報を取得する汎用メソッドを持たせる代わりに、これに使用される Scanner クラスには
各プリミティブ タイプに固有のメソッドがあります。言い換えれば、文字列には Scanner.nextLine()、数値には Scanner.nextInt()、ブール値には Scanner.nextBoolean があります...

Exercício - Simulando Uma Conta Bancária Através Do Terminal

それに比べて、C# には、常に String を返し、その型が変更される標準入力メソッドがあります。


String input = Console.ReadLine();
int.TryParse(input, out number)
Console.WriteLine(number) //completamente válido
ログイン後にコピー
もう少し書かないといけないでしょうか?彼はそうしている。ただし、少なくともすべてのメソッドの構文を覚える必要はなく、1 つだけ覚えて、次に必要な型に変換するだけです。はるかに直感的です。

しかし、続けましょう。この問題を解決するにはまだ長い道のりがあります。次のステップは、ユーザーに登録用の顧客データの入力を求めることです。

ターミナルアカウント.java

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  
        System.out.print("Por favor, insira o número da agência: ");  
        this.branch = sc.nextInt();  

        System.out.print("Por favor, insira o número da conta: ");  
        this.account = sc.nextLine();  

        System.out.print("Por favor, insira o nome do cliente: ");  
        this.clientName = sc.nextLine();  

        System.out.print("Por favor, insira o saldo inicial: ");  
        this.balance = sc.nextDouble();  

        System.out.println("Olá " + this.clientName + ", obrigado por criar uma conta em nosso banco. sua agência é " + this.branch + ", conta " + this.account + " e seu saldo " + this.balance + " já está disponível para saque.");  
    }  
}
ログイン後にコピー
まあ、どうやらすべてが順調のようです。 main メソッドでこのクラスをインスタンス化して、何が起こるか見てみましょう。

Main.java

public class Main {  
    public static void main(String[] args) {  
        TerminalAccount account = new TerminalAccount();  
        account.createAccount();  
    }  
}
ログイン後にコピー

Exercício - Simulando Uma Conta Bancária Através Do Terminal

牛?口座番号の入力が無視され、アルゴリズムがすでに顧客の名前を要求しているのはなぜですか?

Scanner クラスのドキュメントを読むと、どこで停止するかを知るために、ある種の文字を区切り文字として使用して入力をトークンに分割すると説明されています。 .next() メソッドと .hasNext() メソッド (および .nextInt() や .hasNextInt() などのそのバリアント) の場合、区切り文字はスペース、タブ、改行などのグローバル ホワイトスペース (s+) です。 。

このメソッドが行うことは、区切り文字が前にあるトークンを取得し、それを指定された型に変換して、その値を返すことです。残りは入力バッファに残ります。

さて、ここまでは大丈夫です。問題は、文字列
をキャプチャするために使用される .nextLine() メソッドが、改行文字 (n) を破棄する代わりに を消費することです。次に、破棄する別のコマンドの後に使用すると、残されたものを読み取り、すぐに操作を終了し、コードの次の行に進みます。

それは混乱するように聞こえますが、実際その通りです。このフローの狂気を理解するのに役立つ図を作成しました。

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Tá, e como consertamos essa lambança? Simples: adicionando um novo Scanner.nextLine() logo depois do .nextInt() para "limpar" o que sobrou. É bonito? Não, mas resolve.
Dá pra mudar o delimitador para aceitar a quebra de linha (\n ) em vez de um whitespace comum (\s+), mas isso poderia quebrar a forma com que as informações são quebradas em tokens, então é melhor deixar pra lá.

TerminalAccount.java

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  
        System.out.print("Por favor, insira o número da agência: ");  
        this.branch = sc.nextInt();  
        sc.nextLine();

        //...
    } 
}
ログイン後にコピー

Mais feio que bater na mãe.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Beleza, funcionou. Poderíamos dizer que o exercício está completo, mas vamos por um segundo imaginar que o usuário, sem querer, digitou uma letra na hora de colocar o número da agência:

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Eita lasqueira.

Isso acontece porque, como já sabemos, a tipagem do Java é estática e o Scanner está esperando um número mas quando colocamos uma letra junto com um número, essa cadeia se torna uma String. O input que estava esperando um int recebeu uma String e ficou confuso tal qual uma criança que recebe meias de presente de natal.
Exercício - Simulando Uma Conta Bancária Através Do Terminal

Para remediar essa situação, podemos criar um loop simples, que informe para o usuário que a informação que ele inseriu está incorreta de acordo com as especificações do sistema e pedir que ele insira os dados novamente (de maneira correta, dessa vez). Como não sabemos quantas tentativas o usuário vai levar para inserir os dados corretamente, um while parece adequado.

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  

        boolean isBranchNumberInputCorrect = false;  
        do {  
            try {  
                System.out.print("Por favor, insira o número da agência: ");  
                this.branch = sc.nextInt();  
                sc.nextLine();  
                isBranchNumberInputCorrect = true;  
            } catch (InputMismatchException e) {  
                System.out.println("Por favor, insira apenas números inteiros para o número da agência."); 
                sc.nextLine(); 
            }  
        } while (!isBranchNumberInputCorrect);

        //...
    }
}
ログイン後にコピー

Aqui criamos uma variável de controle chamada IsBranchNumberInputCorrect (porque, novamente, sou muito criativo quando se trata de nomes), inicializada em false. Em seguida, começamos o bloco do, uma vez que queremos que o código faça uma ação antes de verificar se o dado inserido é valido ou não e jogamos nosso input lá pra dentro.
Caso dê tudo certo, o dado inserido será armazenado no campo branch, qualquer caractere sobrando será consumido pelo Scanner.nextLine() e a nossa variável de controle será atualizada para true. Aí a condição do while vai checar se isBranchNumberInputCorrect é false. Se for, reinicia o loop no caso de sucesso, o laço é encerrado.

Agora, caso o usuário insira algo não esperado (como uma String), o método Scanner.nextInt() vai emitir um evento de erro InputMismatchException, que será capturado pelo nosso bloco catch. Uma vez lá dentro, o código vai exibir uma mensagem de erro alertando que o tipo de dado está errado e consumido qualquer caractere que tenha ficado pra trás.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

A gente pode fazer a mesma coisa com o input de saldo, para garantir que o valor inserido sempre será numérico e não permitir que a aplicação quebre caso seja inserido algo como 12,56f:

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in); 

        //...

        boolean isBalanceInputCorrect = false;  
        do {  
            try {  
                System.out.print("Por favor, insira o saldo inicial: ");  
                this.balance = sc.nextDouble();  
                sc.nextLine();  
                isBalanceInputCorrect = true;  
            } catch (InputMismatchException e) {  
                System.out.println("Por favor, insira apenas valores decimais.");  
                sc.nextLine();  
            }  
        } while (!isBalanceInputCorrect);  

        //...
    }  
}
ログイン後にコピー

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Poderíamos parar por aqui e dar esse exercício como encerrado, mas ainda tem um bug que requer um pouco de atenção. O que aconteceria se, em vez de delimitarmos nosso saldo com uma vírgula (,) usássemos um ponto (por exemplo, 10.56)?

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Isso acontece devido ao locale, a adaptação do input à cultura do local. Aqui no Brasil, o decimal é delimitado pela vírgula, então o método não entende que essa separação com ponto é válida.
A documentação da classe Scanner nos mostra que é possível alterar a cultura para uma que atenda ou um ou outro padrão, mas não os dois ao mesmo tempo. Também é possível alterar especificamente o delimitador, para um símbolo ou para outro, mas não os dois ao mesmo tempo.

Exercício - Simulando Uma Conta Bancária Através Do Terminal

Um dos métodos para solucionar esse problema não é muito elegante, mas resolve: em vez de capturar o dado diretamente como double, vamos usar o método Scanner.nextLine() para pegar o input como uma String, trocar os pontos por vírgula e tentar trocar o tipo para double.

public class TerminalAccount {  
    private int branch;  
    private String account;  
    private String clientName;  
    private double balance;  

    public void createAccount() {  
        Scanner sc = new Scanner(System.in);  

        //...
        boolean isBalanceInputCorrect = false;  
        do {  
            try {  
                System.out.print("Por favor, insira o saldo inicial: ");  
                String balanceString = sc.nextLine().replace(",", ".");  
                this.balance = Double.parseDouble(balanceString);  
                isBalanceInputCorrect = true;  
            } catch (NumberFormatException e) {  
                System.out.println("Por favor, insira apenas valores decimais.");  
            }  
        } while (!isBalanceInputCorrect);  

        //...

    }  
}
ログイン後にコピー

Além da alteração do método de captura do dado, tivemos mais algumas modificações: retiramos as chamadas para o método Scanner.nextLine() que serviam apenas para consumir os caracteres remanescentes, porque nosso input já faz isso pra gente. Além disso, o tipo do erro mudou: agora não se trata de um erro de incompatibilidade de tipo (InputMismatchException), mas sim um de erro no formato do número (NumberFormatException).
Com essas alterações feitas, bora ver se tudo deu certo:

Exercício - Simulando Uma Conta Bancária Através Do Terminal
Exercício - Simulando Uma Conta Bancária Através Do Terminal

Exercício - Simulando Uma Conta Bancária Através Do Terminal
Deu tudo certo! Com isso, conseguimos dizer que o exercício está concluído (finalmente)!
O repositório desse exercício está disponível aqui caso tenha interesse de ver.

E é isso. Até o próximo módulo!

以上が演習 - 端末を使用した銀行口座のシミュレーションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!