从用户那里获取输入——这段代码中有什么不好的味道?

Getting input from user - What are the bad smells in this code?

我是编码新手,我想要一个示例,说明如何将这些行转换为一个或多个函数...我正在使用 Constructor 进行我的第一个实验,我认为这些行应该'不会出现在我的 Main(?) 中。谢谢!

    do {
        System.out.println("Inserisci il codice, il nome e l'autore del libro che desideri inserire:\n");
                            //Insert book's code, name and author you want to add

                            //code 
        System.out.println("Codice (in numeri):");   //I would like to make a function from here to scan3
        Scanner scan = new Scanner(System.in);
        int c = scan.nextInt();

                            //name
        System.out.println("Nome:");
        Scanner scan2 = new Scanner(System.in);
        String n = scan2.nextLine();

                            //author
        System.out.println("Autore:\n");
        Scanner scan3 = new Scanner(System.in);
        String a = scan3.nextLine();

        Libro book = new Libro (c, n, a);
        System.out.println("Codice: ["+ book.codice + "] Nome: [" + book.nome + "] Autore: [" + book.autore +"]\n" );

                            //Do you want to add a new book?yes/no
        System.out.println("Desideri inserire un nuovo libro?si/no");
        Scanner risposta = new Scanner(System.in);
        risp = risposta.nextLine();

    }while (risp.equals("si") || risp.equals("Si"));
}

}

你可以制作一个函数来获取你的 class 的对象,并在用用户提供的信息填充它后 return 它像这样:

//INPUT FUNCTION
Libro getInput(){
       System.out.println("Codice (in numeri):");
        Scanner scan = new Scanner(System.in);
        int c = scan.nextInt();

                            //name
        System.out.println("Nome:");
        Scanner scan2 = new Scanner(System.in);
        String n = scan2.nextLine();

                            //author
        System.out.println("Autore:\n");
        Scanner scan3 = new Scanner(System.in);
        String a = scan3.nextLine();

     return new Libro(c,n,a);

}



//START YOUR MAIN FUNCTION HERE
do {
        System.out.println("Inserisci il codice, il nome e l'autore del libro che desideri inserire:\n");
        Libro book = getInput();
        System.out.println("Codice: ["+ book.codice + "] Nome: [" + book.nome + "] Autore: [" + book.autore +"]\n" );

                            //Do you want to add a new book?yes/no
        System.out.println("Desideri inserire un nuovo libro?si/no");
        Scanner risposta = new Scanner(System.in);
        risp = risposta.nextLine();

    }while (risp.equals("si") || risp.equals("Si"));
}   

声明一个扫描器并使其成为 class 的成员而不是局部变量。然后,使用这些方法:

private int promptInt(String prompt) {
    System.out.println(prompt); 
    return scan.nextInt();
}

private String promptString(String prompt) {
    System.out.println(prompt);
    return scan.nextLine();
}

然后您可以修改您的代码以利用这些方法。例如,

System.out.println("Codice (in numeri):");
Scanner scan = new Scanner(System.in);
int c = scan.nextInt();

可以替换为

int c = promptInt("Codice (in numeri):");

当您需要提示用户字符串时,使用 promptString 方法。

您的代码中有一些难闻的气味。如果您对难闻的气味不熟悉,我可以说它们是一些糟糕的代码,它们使您的代码 变脏 且不可读,也难以维护和开发,这些代码首先由 Martin M.福勒。我建议你看看他的网站。
您的代码在 Naming Smell 中有一种难闻的气味。 anc 不是很好的变量名,而它们很容易像 namecodiceautore
您代码中的第二个难闻之处是 "Duplicate Code",这意味着类似代码存在于多个地方。在您的代码中,您使用非常相似的代码来获取用户的输入。您可以通过以下方式获取输入:

public static getInputFormUser(String withMessage){
    Scanner scanner=new Scanner(System.in);
    System.out.println(withMessage);
    return scanner.nextLine();
}

现在你的代码应该是这样的:

do {
    System.out.println("Inserisci il codice, il nome e l'autore del libro che desideri inserire:\n");
    int codice = Integer.parse(getInputFormUser("Codice (in numeri): "));
    String nome = getInputFormUser("Nome: ");
    String autore = getInputFromUser("Autore: ");
    Libro book = new Libro (codice, nome, autore);
    System.out.println("Codice: ["+ book.codice + "] Nome: [" + book.nome + "] Autore: [" + book.autore +"]\n" );

                        //Do you want to add a new book?yes/no
    String risp = getInputFormUser("Desideri inserire un nuovo libro?si/no");

}while (risp.equals("si") || risp.equals("Si"));

另外,您可以创建一个方法来通过一次调用获取整个 Libro 个实例。而不是以这种方式打印 book 对象,您可以像这样覆盖 Libro class 中的 toString() 方法:

public String toString (){
    return "Codice: ["+ this.codice + "] Nome: [" + this.nome + "] Autore: [" +             
                 this.autore +"]";
}

并且只需调用 System.out.println(book);,因为它会在每个对象上调用 .toString()