質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.70%

どの処理をメソッド化し一つのクラスにまとめたら良いのか分かりません

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 476

TomoShimizu

score 10

Java初心者です。
同じようなコードをメソッド化し一つのクラスにまとめたいのですが、どこを切り離せば良いか分かりません。

例えば、下記2つのコードは「Scannerメソッドで数値を取得し、入力された数値に対応する文字列を返す」というプログラムなのですが、どこから切り分けてメソッド化し、一つのクラスに分ければいいのかさっぱり分からず困っています。

ここで知りたいことは、
・下記2つの場合、一つにまとめられる処理はあるのか?
・もしあるなら、どこの処理から切り離すのがいいのか?
・Scannerメソッドは毎回インスタンス化しなければいけないのか?
です。

ご回答いただけますと幸いです。
※メソッドやクラスについては一通り学んだつもりですが、理解が浅くまだまだ未熟なことは承知の上です。

package advanced_chapter1;
import java.util.InputMismatchException;
import java.util.Scanner;

public class task_05 {
    public static void main(String[] args) {

        // 変数の定義
        int a = 0;
        int b = 0;

        try {
            // scannerをインスタンス化
            Scanner scanner = new Scanner(System.in);

            // 起動時に文字列を表示
            System.out.print("整数値a:");
            // 整数値aを読み込む
            a = scanner.nextInt();

            // 文字列を表示
            System.out.print("整数値b:");
            // 整数値bを読み込む
            b = scanner.nextInt();

            scanner.close();

            if (a > b) {
                System.out.println("大きいほうの値は" + a + "です。");
            } else if (a < b) {
                System.out.println("大きいほうの値は" + b + "です。");
            } else {
                System.out.println(a + "と" + b + "はどちらも同じ値です。");
            }

        // 整数値以外の値が入力された場合の例外処理
        } catch (InputMismatchException e) {
            System.out.println("整数値を入力してください。");
        }
    }
}
package advanced_chapter1;

import java.util.InputMismatchException;
import java.util.Scanner;

public class task_04 {
    public static void main(String[] args) {

        // 変数の定義
        int num = 0;

        try {
            // scannerをインスタンス化
            Scanner scanner = new Scanner(System.in);

            // 起動時に文字列を表示
            System.out.print("点数:");
            // 整数値(点数)を読み込む
            num = scanner.nextInt();

            scanner.close();

            // numの値が負の数だった場合の処理
            if (num < 0) {
                System.out.println("不正な点数です。");
            } else if (num > 100) {
                System.out.println("100より小さい点数を入力してください。");
            // numの値が80以上100以下の場合の処理
            } else if (num >= 80 && num <= 100) {
                System.out.println("優");
            // numの値が70以上80未満の場合の処理
            } else if (num >= 70 && num < 80) {
                System.out.println("良");
            // numの値が60以上70未満の場合の処理
            } else if (num >= 60 && num < 70) {
                System.out.println("可");
            // numの値が60未満の場合の処理
            } else {
                System.out.println("不可");
            }
        // 整数値以外の値が入力された場合の例外処理
        } catch (InputMismatchException e) {
            System.out.println("点数(整数値)を入力してください。");
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/02/18 16:53

    質問に「初心者アイコン」をつけてください(本文やタイトルは要件を書くことに終始してください)
    また、この手の質問(というか依頼っぽいですが)は好みによるところが結構出ます。目指しているところを明示されたほうが良いように思います。

    キャンセル

  • m.ts10806

    2019/02/18 16:54

    つまり「やろうとすればどこまでもできるし、落としどころが難しい」話で、「絶対の答え」がないわけです。
    リファクタリングでがっつりコードを書き換える人もいるでしょうし、
    現在のコードを切り分けるだけの人もいるでしょうし

    要は質問者さんがどの程度なら理解をできるか、です。
    単にコードもらっても考え方を学ばないと意味がありませんしね・・・

    キャンセル

  • azuapricot

    2019/02/18 16:57 編集

    個人的な見解なので、追記で失礼します~。

    この程度の長さであれば無理にメソッドやクラスを分ける方が返ってわかりにくくなるかもしれませんね。
    目安としては、1画面に収まるくらいであればそのままでよいのでは?と思います。

    しいて言うなら、計算して出力している部分を計算メソッドとしてわける・・・?とかでしょうか。
    scannerはどこかから引数としてもらう・・・というのでなければ毎回インスタンス化しなければいけないと思います。

    キャンセル

回答 3

checkベストアンサー

+1

課題でしょうか.
プログラムは入力→処理→出力が基本構造です.
それに沿って二つのコードの異なる部分, 同じ部分を抜き出してみましょう.

package advanced_chapter1;

import java.util.InputMismatchException;
import java.util.Scanner;

public class task_common {

    //入力(1件)
    static int input(String prompt, Scanner scanner) throws InputMismatchException {
        // 文字列(プロンプト)を表示
        System.out.print(prompt);
        // 整数値を読み込んで返す.
        return scanner.nextInt();
    }

    //出力
    static void output(String text) {
        System.out.println(text);
    }
}
package advanced_chapter1;

import java.util.InputMismatchException;
import java.util.Scanner;

public class task_05 {
    public static void main(String[] args) {

        // 変数の定義
        int a = 0;
        int b = 0;

        try {
            // scannerをインスタンス化
            Scanner scanner = new Scanner(System.in);

            // 整数値aを読み込む
            a = task_common.input("整数値a:", scanner);

            // 整数値bを読み込む
            b = task_common.input("整数値b:", scanner);

            scanner.close();

            String text = process(a, b);

            task_common.output(text);

        // 整数値以外の値が入力された場合の例外処理
        } catch (InputMismatchException e) {
            System.out.println("整数値を入力してください。");
        }
    }

    //task_05処理
    static String process(int a, int b) {
        if (a > b) {
            return "大きいほうの値は" + a + "です。";
        } else if (a < b) {
            return "大きいほうの値は" + b + "です。";
        } else {
            return a + "と" + b + "はどちらも同じ値です。";
        }
    }
}
package advanced_chapter1;

import java.util.InputMismatchException;
import java.util.Scanner;

public class task_04 {
    public static void main(String[] args) {

        // 変数の定義
        int num = 0;

        try {
            // scannerをインスタンス化
            Scanner scanner = new Scanner(System.in);

            // 整数値(点数)を読み込む
            num = task_common.input("点数:", scanner);

            scanner.close();

            String text = process(num);

            task_common.output(text);

        // 整数値以外の値が入力された場合の例外処理
        } catch (InputMismatchException e) {
            System.out.println("点数(整数値)を入力してください。");
        }
    }

    //task_04処理
    static String process(int num) {
        // numの値が負の数だった場合の処理
        if (num < 0) {
            return "不正な点数です。";
        } else if (num > 100) {
            return "100より小さい点数を入力してください。";
        // numの値が80以上100以下の場合の処理
        } else if (num >= 80 && num <= 100) {
            return "優";
        // numの値が70以上80未満の場合の処理
        } else if (num >= 70 && num < 80) {
            return "良";
        // numの値が60以上70未満の場合の処理
        } else if (num >= 60 && num < 70) {
            return "可";
        // numの値が60未満の場合の処理
        } else {
            return "不可";
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/18 21:05

    なるほど…!恥ずかしながら、try catchの中に全ての処理を書かないといけないと思っておりました…。
    このように切り分けるのですね!もっとメソッド・クラスについて勉強していきます。
    ありがとうございます!

    キャンセル

  • 2019/02/18 22:24

    これで意味合い的に全て try - catch の中に書いてあることになります.

    一応クラスを分けた形になっていますが, これではオブジェクト指向としてのクラスの使われ方ではありませんので, ご注意ください. (学習の課題でしたら, 今後ちゃんとオブジェクトが出てくると思いますが.)

    キャンセル

0

オブジェクトを使用した(大袈裟な)...サンプルです.
System.in(&Scanner), System.out が 表立って出なくなり, Task04 と Task05 の main メソッドが new TaskXX() 以外同じになりました.
『質問への~依頼』で mts10806 さんの仰られている「やろうとすればどこまでもできる~」の一例といった所でしょうか.

package advanced_chapter1;

public interface Task {
  /**
   * ConsoleManager から必要な値を取り込む.
   * @param console
   * @return 正常に読み込めた場合 true. 読み込めなかった場合 false
   */
  boolean read(ConsoleManager console);

  /**
   * 処理結果を文字列で返す.
   * @return 処理結果
   */
  String getResultString();

  /**
   * 異常が発生した場合のエラーメッセージを返す
   * @return
   */
  String getErrorMessage();
}
package advanced_chapter1;

import java.util.InputMismatchException;
import java.util.Scanner;

class ConsoleManager {
  private Scanner scanner = null;

  public ConsoleManager() {
    // scannerをインスタンス化
    scanner = new Scanner(System.in);
  }

  public int inputInt(String prompt) throws InputMismatchException {
    // 文字列(プロンプト)を表示
    System.out.print(prompt);
    // 整数値を読み込んで返す.
    return scanner.nextInt();
  }

  public void output(String text) {
    System.out.println(text);
  }

  public void error(String errmsg) {
    System.err.println(errmsg);
  }

  public void close() {
    if(scanner != null) scanner.close();
  }
}
package advanced_chapter1;

import java.util.InputMismatchException;

public class Task_04 implements Task {
  public static void main(String[] args) {
    Task task = new Task_04();
    ConsoleManager console = new ConsoleManager();
    try {
      if(task.read(console)) {
        console.output(task.getResultString());
      } else {
        console.error(task.getErrorMessage());
      }
    } finally {
      console.close();
    }
  }

  // 変数の定義
  private int num;
  private String errmsg;

  /**
   * InputManager から必要な値を取り込む.
   * @param inputManager
   * @return 正常に読み込めた場合 true. 読み込めなかった場合 false
   */
  @Override
  public boolean read(ConsoleManager console) {
    try {
      // 整数値(点数)を読み込む
      num = console.inputInt("点数:");

      return true;

      // 整数値以外の値が入力された場合の例外処理
    } catch (InputMismatchException e) {
      errmsg = "点数(整数値)を入力してください。";
    }
    return false;
  }

  /**
   * 処理結果を文字列で返す.
   * @return 処理結果
   */
  @Override
  public String getResultString() {
    // numの値が負の数だった場合の処理
    if (num < 0) {
      return "不正な点数です。";
    } else if (num > 100) {
      return "100より小さい点数を入力してください。";
      // numの値が80以上100以下の場合の処理
    } else if (num >= 80 && num <= 100) {
      return "優";
      // numの値が70以上80未満の場合の処理
    } else if (num >= 70 && num < 80) {
      return "良";
      // numの値が60以上70未満の場合の処理
    } else if (num >= 60 && num < 70) {
      return "可";
      // numの値が60未満の場合の処理
    }
    return "不可";
  }

  /**
   * 異常が発生した場合のエラーメッセージを返す
   * @return
   */
  @Override
  public String getErrorMessage() {
    return errmsg;
  }
}
package advanced_chapter1;

import java.util.InputMismatchException;

public class Task_05 implements Task {
  public static void main(String[] args) {
    Task task = new Task_05();
    ConsoleManager console = new ConsoleManager();
    try {
      if(task.read(console)) {
        console.output(task.getResultString());
      } else {
        console.error(task.getErrorMessage());
      }
    } finally {
      console.close();
    }
  }

  // 変数の定義
  private int a;
  private int b;
  private String errmsg;

  /**
   * ConsoleManager から必要な値を取り込む.
   * @param console
   * @return 正常に読み込めた場合 true. 読み込めなかった場合 false
   */
  @Override
  public boolean read(ConsoleManager console) {
    try {
      // 整数値aを読み込む
      a = console.inputInt("整数値a:");

      // 整数値bを読み込む
      b = console.inputInt("整数値b:");

      return true;

      // 整数値以外の値が入力された場合の例外処理
    } catch (InputMismatchException e) {
      errmsg = "整数値を入力してください。";
    }
    return false;
  }

  /**
   * 処理結果を文字列で返す.
   * @return 処理結果
   */
  @Override
  public String getResultString() {
    if (a > b) {
      return "大きいほうの値は" + a + "です。";
    } else if (a < b) {
      return "大きいほうの値は" + b + "です。";
    }
    return a + "と" + b + "はどちらも同じ値です。";
  }

  /**
   * 異常が発生した場合のエラーメッセージを返す
   * @return
   */
  @Override
  public String getErrorMessage() {
    return errmsg;
  }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

入力を促すメッセージの配列、
入力が整数でなかった時のエラーメッセージ、
入力された整数に対して行う処理
の3つを受け取って、整数の入力と処理を行うクラスを定義してみました。

package advanced_chapter1;

import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;
import java.util.function.Consumer;

class Task {
    private String[] messages;
    private String err_message;
    private List<Integer> data = new ArrayList<Integer>();
    private Consumer<int[]> consumer;

    public Task(String[] messages, String err_message, Consumer<int[]> consumer) {
        this.messages = messages;
        this.err_message = err_message;
        this.consumer = consumer;
    }

    public void run() {
        input();
        int[] int_ary = new int[data.size()];
        for (int i = 0; i < data.size(); i++) {
            int_ary[i] = data.get(i).intValue();
        }
        consumer.accept(int_ary);
    }

    private void input() {
        Scanner scanner = new Scanner(System.in);
        for (String s : messages) {
            while (true) {
                try {
                    System.out.print(s);
                    int num = scanner.nextInt();
                    data.add(num);
                    break;
                } catch (InputMismatchException e) {
                    scanner.nextLine();
                    System.out.println(err_message);
                }
            }
        }
        // scanner.close();
    }
}

public class task_xxx {
    public static void main(String[] args) {
        new Task(
                new String[] { "整数値a:", "整数値b:" }, "整数値を入力してください。",
                nums -> action_05(nums)
        ).run();

        new Task(
                new String[] { "点数:" }, "点数(整数値)を入力してください。", 
                nums -> action_04(nums)
        ).run();
    }

    static void action_05(int[] nums) {
        int a = nums[0];
        int b = nums[1];
        if (a > b) {
            System.out.println("大きいほうの値は" + a + "です。");
        } else if (a < b) {
            System.out.println("大きいほうの値は" + b + "です。");
        } else {
            System.out.println(a + "と" + b + "はどちらも同じ値です。");
        }
    }

    static void action_04(int[] nums) {
        int num = nums[0];
        if (num < 0) {
            System.out.println("不正な点数です。");
        } else if (num > 100) {
            System.out.println("100より小さい点数を入力してください。");
        } else if (num >= 80 && num <= 100) {
            System.out.println("優");
        } else if (num >= 70 && num < 80) {
            System.out.println("良");
        } else if (num >= 60 && num < 70) {
            System.out.println("可");
        } else {
            System.out.println("不可");
        }
    }
}

実行例
イメージ説明

        new Task(
                new String[] { "整数値a:", "整数値b:" }, "整数値を入力してください。",
                nums -> action_05(nums)
        ).run();


で質問文の task_05 の処理をしています。
入力を促すメッセージを2つ渡しているので、内部では 2 つの整数を取得します。
action_05(nums) として、 2 つの整数の比較結果を出力する処理を定義しています。

        new Task(
                new String[] { "点数:" }, "点数(整数値)を入力してください。", 
                nums -> action_04(nums)
        ).run();


では、質問文の task_04 の処理をしています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.70%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る