对于我用 Java 编写的作业(我是新手),我遇到了创建控制台命令列表的问题。用户将面对一组命令,他/她将在其中选择一个数字。像这样:
Enter your choice:
0) Create a Table
1) List All Tables
2) Delete a Table
3) Insert a Record
4) List All Records
5) Delete a Record
6) Find a Record(by =)
7) Find a Record(by >)
8) Find a Record(by <)
9) Exit
我做的第一种方法如下(不需要的代码部分被截断):
...
outerLoop: while (true) {
Scanner s = new Scanner(System.in);
try {
while (true) {
System.out.println("Enter your choice:");
displayChoiceList();
int choice = s.nextInt();
switch (choice) {
case 1:
processTableCreation();
break;
case 2:
catalog.listAllTables();
break;
case 3:
System.out.println("Enter the name of table:");
String tableName = s.nextLine();
catalog.deleteTable(tableName);
break;
case 4:
processRecordInsertion();
break;
case 5:
processListAllRecords();
break;
case 6:
processDeleteRecord();
break;
case 7:
processFindRecord(Constants.Operator.EQUAL);
break;
case 8:
processFindRecord(Constants.Operator.SMALLER);
break;
case 9:
processFindRecord(Constants.Operator.GREATER);
break;
case 10:
break outerLoop;
}
}
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
return;
}
}
...
private static void displayChoiceList() {
String[] choices = new String[] { "Create Table", "List All Tables",
"Delete a Table", "Insert a Record to a Table",
"List all records", "Delete a record",
"Find by Primary Key(=)", "Find by Primary Key(<)",
"Find by Primary Key(>)", "Exit" };
int id = 0;
for (String choice : choices) {
System.out.println((id + 1) + ") " + choice);
++id;
}
}
然后,认为这很丑陋,为了试验枚举,我尝试了以下方法:
private enum Command {
CREATE_TABLE("Create a Table"),
LIST_ALL_TABLES("List All Tables"),
DELETE_TABLE("Delete a Table"),
INSERT_RECORD("Insert a Record"),
LIST_ALL_RECORDS("List All Records"),
DELETE_RECORD("Delete a Record"),
FIND_RECORD_EQ("Find a Record(by =)"),
FIND_RECORD_GT("Find a Record(by >)"),
FIND_RECORD_LT("Find a Record(by <)"),
EXIT("Exit");
private final String message;
Command(String message) {
this.message = message;
}
public String message() { return this.message; }
}
...
outerLoop: while (true) {
Scanner s = new Scanner(System.in);
try {
while (true) {
System.out.println("Enter your choice:");
displayChoiceList();
int choice = s.nextInt();
if (choice == Command.CREATE_TABLE.ordinal())
processTableCreation();
else if (choice == Command.LIST_ALL_TABLES.ordinal())
catalog.listAllTables();
else if (choice == Command.DELETE_TABLE.ordinal()) {
System.out.println("Enter the name of table:");
String tableName = s.nextLine();
catalog.deleteTable(tableName);
}
else if (choice == Command.INSERT_RECORD.ordinal())
processRecordInsertion();
else if (choice == Command.LIST_ALL_RECORDS.ordinal())
processListAllRecords();
else if (choice == Command.DELETE_RECORD.ordinal())
processDeleteRecord();
else if (choice == Command.FIND_RECORD_EQ.ordinal())
processFindRecord(Constants.Operator.EQUAL);
else if (choice == Command.FIND_RECORD_LT.ordinal())
processFindRecord(Constants.Operator.SMALLER);
else if (choice == Command.FIND_RECORD_GT.ordinal())
processFindRecord(Constants.Operator.GREATER);
else if (choice == Command.EXIT.ordinal())
break outerLoop;
else
System.out.println("Invalid command number entered!");
}
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
return;
}
}
...
private static void displayChoiceList() {
for (Command c : Command.values())
System.out.println(c.ordinal() + ") " + c.message());
}
实际上,我的想法是使用 Enum 的 in switch 及其序数值,但 Java 不允许在 switch 情况下使用非常量值。解决这个问题的正确方法是什么?最优雅/可扩展/灵活?非常感谢任何建设性意见!
最佳答案
您可以使用 Command.values()
,它包含按顺序排列的枚举:
switch (Command.values[number]) {
case CREATE_A_TABLE:
...
}
一种更优雅和可维护的方法是使用多态性来消除 switch 语句:
abstract class Command {
private String name;
protected Command(String name) {
this.name = name;
}
@Override public String toString() {
return name;
}
public abstract void execute();
}
和其他地方:
Command[] commands = {
new Command("Create a table") {
@Override public void execute() {
// code to create a table
}
},
new Command("List all tables") {
@Override public void execute() {
// code to list all tables
}
}
};
for (int i = 0; i < commands.length; i++) {
System.out.println(i + ":" + command);
}
int number = getInput();
commands[number].execute();
优点:
- 更短、更清晰的代码
- 编译器检查每个命令是否已实现(使用 switch 语句,您可以忘记添加 case 语句,这种错误只会在运行时发生。当然,如果您忘记了 case when,一个好的编译器会发出警告切换枚举,但比编译错误更容易错过警告)。 ==> 在维护期间更稳健。
关于java - 创建控制台命令列表——如何正确使用 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5904431/