Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

242
Vistas
Reutilización de código: devolución de listas de campos de enumeración con métodos getter comunes

Tengo dos enumeraciones:

Opciones del menú principal

 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()); } }

Opciones de método de selección de host

 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()); } }

Ambas enumeraciones comparten el mismo campo.

 private final String message;

el mismo captador

 public String getMessage() { return message; }

Y lo mismo que el método ListString()

 public static List<String> asListString() { return Arrays.stream(MainMenuOptions.values()) .map(MainMenuOptions::getMessage) .collect(Collectors.toList()); }

¿Cómo puedo SECAR estas enumeraciones?

Espero tener más enumeraciones con los mismos campos y métodos, y parece una tontería escribir lo mismo una y otra vez para cada uno.

  • Intenté hacer que ambas enumeraciones extiendan una superclase, pero las enumeraciones no pueden tener cláusulas extendidas
  • Puedo crear una interfaz que especifique el contrato para el método asListString(), pero eso no me permite reutilizar ningún código.

El sabor que esperaba que el código pudiera tener es algo como esto:

 public class Utils { public static List<String> enumAsListString(Enum e) { return e.values().stream.map(e::getMessage).collect(Collectors.toList()); } }
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Este es probablemente uno de los casos en los que debe elegir uno entre SECO y usar enumeraciones.

Las enumeraciones no van muy lejos en lo que respecta a la reutilización de código, al menos en Java; y la razón principal de esto es que los beneficios principales del uso de enumeraciones se obtienen en código estático; me refiero a estático como en "no dinámico"/"tiempo de ejecución", en lugar de static :). Aunque puede "reducir" la duplicación de código, difícilmente puede hacer mucho de eso sin introducir dependencia (sí, eso se aplica a agregar una API/interfaz común, extrayendo la implementación de asListString a una clase de utilidad). Y eso sigue siendo una compensación indeseable.

Además, si debe usar una enumeración (por razones tales como soporte incorporado para serialización, mapeo de base de datos, enlace JSON o, bueno, porque es enumeración de datos, etc.), no tiene más remedio que duplicar declaraciones de métodos a un medida, incluso si puede compartir la implementación: los métodos estáticos simplemente no se pueden heredar, y los métodos de interfaz (de los cuales getMessage sería uno) necesitarán una implementación en todas partes. Me refiero a que esta forma de ser "DRY" tendrá muchas formas de ser poco elegante.

Si yo fuera usted, simplemente haría que estos datos fueran completamente dinámicos.

 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); } }

Esto es muy escalable, aunque presenta la necesidad de validar datos donde las enumeraciones evitarían de forma estática malas opciones, y posiblemente código personalizado donde una enumeración ofrecería soporte integrado.

Se puede mejorar con una enumeración de "categoría", que brinda acceso estático a las listas de menú y un solo lugar para 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()); } }

Debería quedar claro que puede reemplazar class MenuOption con un montón de enumeraciones que implementan una interfaz común, que debería cambiar poco o nada en MenuCategory . Yo no haría eso, pero es una opción.

over 4 years ago · Santiago Trujillo Denunciar

0

Puedes SECARLO un poco.

Utils.java

 import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public interface Utils<T> { public String getMessage(); public static <T extends Utils<T>> List<String> asListString(Class<T> clazz) { return Arrays.stream(clazz.getEnumConstants()) .map(T::getMessage) .collect(Collectors.toList()); } }

HostSelectionMethodOptions.java

 public enum HostSelectionMethodOptions implements Utils<HostSelectionMethodOptions> { FIND_ALL("Find all"), FIND_BY_LASTNAME_PREFIX("Find by last name prefix"), FIND_BY_CITY_STATE("Find by city & state"); private final String message; HostSelectionMethodOptions(String message) { this.message = message; } public String getMessage() { return message; } }

Entonces solo haz esto: Utils.asListString(HostSelectionMethodOptions.class);

over 4 years ago · Santiago Trujillo Denunciar

0

Básicamente tuve la misma idea que davidalayachew.

Una enumeración puede implementar una interfaz. Entonces, si crea un asListString común que acepta un tipo de enum , podría obtener el resultado deseado.

Primero, cree una interfaz de Options y deje que ambos enum la implementen:

 interface Options { String getMessage(); }
 enum HostSelectionMethodOptions implements Options { ... } enum MainMenuOptions implements Options { ... }

Ahora crea un método como este:

 public static <T extends Enum<T> & Options> List<String> asListString(Class<T> type) { return Arrays.stream(type.getEnumConstants()) .map(T::getMessage) .collect(Collectors.toList()); }

El método declara un argumento de tipo: <T extends Enum<T> & Options> . Aquí, T es un tipo de intersección , por lo que extiende tanto Enum como la interfaz de Options . Puedes llamarlo así:

 asListString(MainMenuOptions.class);
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda