Javaプログラミングを学んでいます。BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
ユーザーからの入力を取得する必要があるすべてのメソッドで、何度も何度も書く必要がありますか? 他の代替案が存在する場合は、親切に提案してください。
4 に答える
おそらく、アプリケーションの設計をもっと慎重に検討する必要があります。
通常、ユーザーとの対話とアプリケーションのロジックを分離することは非常に良い考えです。
理想的には、aBufferedReader
と何かの両方をカプセル化してコンソールに出力し、必要な入力を取得して、ユーザーが知っておくべき情報をユーザーに表示するメソッドを提供するクラスを作成します。
これを機能させるには、そのクラスの新しいインスタンスを作成し、それをユーザーと対話する必要があるすべてのクラスに渡す必要があります。
このようにして、アプリケーションの明確な懸念を明確に分離し、この分離によりアプリケーションの保守性が向上します。たとえば、テキスト形式のユーザー インターフェイスに加えて、グラフィカル ユーザー インターフェイスを作成する必要があるとしたらどうなるでしょうか。
ユース ケースに応じて、次の 2 つの回答が考えられます。
デバッグに出力ストリームを使用している場合は、(それが機能する限り) 好きなことをしてください。それはあなたのコードです。他のユーザーの回答はこれに適しています。
ただし、実際のプログラムに使用する場合は、次のいずれかを実行する必要があります。
- 出力ストリームをパラメータとして、それを使用する各メソッドに渡します。または
- 各メソッドに、メイン プログラムが出力する文字列を返すようにします。
「有効な値を入力するまでユーザーに入力を促す」などの主要な入力/出力メソッドの場合、次のようにストリームをパラメーターとして渡す必要があります。
正しくない:
public static void main(String[] args){
promptUserForInput();
}
public static int promptUserForInput(){
Scanner in = new Scanner(System.console().reader());
PrintWriter out = System.console().writer();
out.print("Enter an integer:");
// [...]
}
正しい:
public static void main(String[] args){
promptUserForInput(System.console());
}
public static int promptUserForInput(Console io){
Scanner in = new Scanner(io.reader());
PrintWriter out = io.writer();
out.print("Enter an integer:");
// [...]
}
メソッドがユーザーとのライブ対話を必要としないもう 1 つのケースではString
、対話メソッドが使用するオブジェクトを返す必要があります。
正しくない:
public static void main(String[] args){
printMsg("bob", "tuna fish", "pickles", "rye");
}
public static String printMsg(String person, String type, String topping, String bread){
System.out.printf("%1$s wants a %2$s sandwich with %3$s on %4$s bread%n",
person, type, topping, bread);
}
正しい:
public static void main(String[] args){
System.out.println(generateMsg("bob", "tuna fish", "pickles", "rye"));
}
public static String generateMsg(String person, String type, String topping, String bread){
return String.format("%1$s wants a %2$s sandwich with %3$s on %4$s bread",
person, type, topping, bread);
}
もう1つの改善点があり、これはあなたの質問のポイントにもっと到達すると思います. ファクトリ クラスを作成して、リーダーとライターをインスタンス化できます。
public class InputFactory {
public static InputStreamReader inStreamReader(InputStream in){
return new InputStreamReader(in);
}
public static BufferedReader bufferedReader(InputStream in){
return new BufferedReader(inStreamReader(in));
}
public static Scanner scanner(InputStream in){
return new Scanner(inStreamReader(in));
}
}
これには好きなだけオーバーロードを追加できるため、関数を 1 つだけ呼び出して、任意の入力ストリーム、またはファイルなどの他の潜在的な入力ソースから目的の入力ストリーム タイプを構築できます。から を取得するにBufferedReader
はInputStream
、 を呼び出しますInputFactory.bufferedReader(myInputStream)
。まだ少し長いですが、Eclipse のオートコンプリート機能を使用すると、すぐに入力できますが、チェーンされたコンストラクターを使用するだけではうまくいきません。
static
変数にすることができます:
public static BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
それに応じて、関連する各メソッドからアクセスします。
また、Scanner
ユーザーからの入力をより簡単に読み取るためのユーティリティ クラスである も参照してください。
@mariosangiorgio が指摘しているように、プログラムのどの部分が何をしているのかを考慮することが重要です。通常、コードは論理的に一貫性のあるチャンクに分割する必要があります。これは、I/O を処理するコードをコア ロジックを処理するコードから分離することを意味します。したがって、重要なアプリケーションを設計する場合static
、特定のコンテキストで「コード分離」というこの哲学を弱体化させる可能性があるため、-variable アプローチは最良のアプローチではない可能性があります。とはいえ、学習中の人にとっては問題ないはずです。