我有兩個列舉:
主選單選項
public enum MainMenuOptions {
EXIT("Exit"),
VIEW_RESERVATIONS("View Reservations By Host"),
CREATE_RESERVATION("Create A Reservation"),
EDIT_RESERVATION("Edit A Reservation"),
CANCEL_RESERVATION("Cancel A Reservation");
private final String message;
MainMenuOptions(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public static List<String> asListString() {
return Arrays.stream(MainMenuOptions.values())
.map(MainMenuOptions::getMessage)
.collect(Collectors.toList());
}
}
主機選擇方法選項
public enum HostSelectionMethodOptions {
FIND_ALL("Find all"),
FIND_BY_LASTNAME_PREFIX("Find by last name prefix"),
FIND_BY_CITY_STATE("Find by city & state");
String message;
HostSelectionMethod(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public static List<String> asListString() {
return Arrays.stream(HostSelectionMethod.values())
.map(HostSelectionMethod::getMessage)
.collect(Collectors.toList());
}
}
兩個列舉共享相同的欄位
private final String message;
相同的吸氣劑
public String getMessage() {
return message;
}
和同樣的 asListString() 方法
public static List<String> asListString() {
return Arrays.stream(MainMenuOptions.values())
.map(MainMenuOptions::getMessage)
.collect(Collectors.toList());
}
我怎樣才能干掉這些列舉?
我希望有更多具有相同欄位和方法的列舉,并且為每個列舉一遍又一遍地寫出相同的東西似乎很愚蠢。
- 我嘗試讓兩個列舉都擴展超類,但列舉不能有擴展子句
- 我可以創建一個介面來指定 asListString() 方法的契約,但這不允許我實際重用任何代碼
我希望代碼可以具有的風格是這樣的:
public class Utils {
public static List<String> enumAsListString(Enum e) {
return e.values().stream.map(e::getMessage).collect(Collectors.toList());
}
}
uj5u.com熱心網友回復:
這可能是您需要在 DRY 和使用列舉之間選擇一種的情況之一。
就代碼重用而言,列舉并沒有走多遠,至少在 Java 中是這樣;并且這種情況的主要原因是,使用列舉的主要優點在靜態代碼的收獲-我的意思是靜態的,如“不動” /“運行”,而不是static:)。盡管您可以“減少”代碼重復,但如果不引入依賴項,您幾乎無法做到這一點(是的,這適用于添加公共 API/介面,將 的實作提取asListString到實用程式類)。這仍然是一個不受歡迎的權衡。
此外,如果您必須使用列舉(出于對序列化、資料庫映射、JSON 系結的內置支持,或者因為它是資料列舉等原因),您別無選擇,只能將方法宣告復制到在某種程度上,即使您可以共享實作:靜態方法不能被繼承,并且介面方法(其中getMessage之一)在任何地方都需要一個實作。我的意思是這種“干”的方式會有很多不優雅的方式。
如果我是你,我會讓這些資料完全動態化
final class MenuOption {
private final String category; //MAIN_MENU, HOT_SELECTION
private final String message; //Exit, View Reservation By Host, etc.
public static MenuOption of(String key, String message) {
return new MenuOption(key, message);
}
}
這是非常可擴展的,盡管它引入了驗證資料的需要,其中列舉可以靜態防止錯誤選項,并且可能需要自定義代碼,其中列舉將提供內置支持。
它可以通過“類別”列舉進行改進,它提供對選單串列的靜態訪問,以及一個地方asListString():
enum MenuCategory {
MAIN_MENU(
MenuOption.of("Exit"),
MenuOption.of("View Reservations By Host")
),
HOT_SELECTION(
MenuOption.of("Find All")
);
private final List<MenuOption> menuOptions;
MenuCategory(MenuOption... options) {
this.menuOptions = List.of(options); //unmodifiable
}
public List<String>asListString() {
return this.menuOptions.stream()
.map(MenuOption::getMessage)
.collect(Collectors.toList());
}
}
應該清楚的是,您可以class MenuOption用一堆實作通用介面的列舉替換,在MenuCategory. 我不會那樣做,但這是一種選擇。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/402536.html
標籤:
