Java - enum un poco peculiar

 
Vista:

enum un poco peculiar

Publicado por juan (43 intervenciones) el 25/09/2018 00:29:42
Hola, tengo problemillas con Java y era para ver si alguién podría ayudarme un poquito jeje...
Necesito relacionar unas constantes con unos objetos, y necesito poder saber también a que constante se atribuye cada objeto, o si no se atribuye a ninguna de estas. Mi idea es la siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Main {
 
    enum Foo {
        CONSTANTE1("soy la primera!"),
        CONSTANTE2("soy la segunda!");
 
        private final String constante;
 
        Foo(String constante) {
            this.constante = constante;
        }
 
        public String getValor() {
            return constante;
        }
 
        public static Foo getConstante(String valor) {
            for(Foo i:values()) {
                if(valor.equals(i.getValor())) {
                    return i;
                }
            }
            return null;
        }
    }
 
    public static void main(String[] args) {
 
        Foo result = Foo.getConstante("soy la primera!");
        System.out.println(result);
        result = Foo.getConstante("soy la tercera!");
        System.out.println(result);
 
    }
}

Resultado:
CONSTANTE1
null

No me parece algo demasiado "atractivo" por así decirlo, pero no se me ocurre nada mejor y por eso os pregunto a los que si sabeis programar bien.

Ah, con lo de atractivo me refiero a que tengo que hacer varios enum que hagan esta función, por lo que tendría que estar copiano y pegando el mismo método estático en cada uno de ellos, por lo de que no permiten extender y tal...

Gracias de antemano!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 755
Bronce
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

enum un poco peculiar

Publicado por Yamil Bracho (2315 intervenciones) el 25/09/2018 00:42:18
Puedes colocar las constante sen un HashMap y de alli buscar su valor. Sreia algo como :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static class Foo {
	private static Map<String, String> map = new HashMap<String, String>();
 
	private static Foo() {
	  map.put("CONSTANTE1","soy la primera!");
	  map.put("CONSTANTE2","soy la segunda!");
	}
 
	private static String getConstante(string key) {
	   return map.get(key);
	}
}
 
 
string result = Foo.getConstante("soy la primera!");
System.out.println(result);
 
result = Foo.getConstante("soy la tercera!");
System.out.println(result);
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

enum un poco peculiar

Publicado por juan (43 intervenciones) el 25/09/2018 01:19:58
El programa que quiero hacer es muy extenso, pero el punto en el que me encuentro ahora mismo es que tengo un documento XML con la estructura de la base de datos de la que se quieren extraer los datos, algo así:
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
 
<config>
	<datastructure>
		<database fieldname="DataBase" user="root" password="xxxx">
			<table fieldname="Table">
				<column fieldname ="UserNames"/>
			</table>
		</database>
	</datastructure>
</config>
La idea que tuve es crear una clase llamada XMLTag, que contiene el nombre de la tag y los atributos que cada una de las tag del documento XML puede tener. Una vez instanciada XMLTag permite asignar un valor a cada uno de los atributos que ésta tiene (sí, algo así como un HashMap, pero con funciones más específicas y más facil de manejar).
Mi idea a la hora de procesar el documento XML, era la de crear un enum con las constantes que va a tener una base de datos (TABLAS, COLUMNAS, FILAS, CELDAS), y relacionar cada una de las constantes con su correspondiente XMLTag, para que así pueda hacer un switch donde cada caso corresponda a una de las constantes, y poder preparar el statement sql. Éstos XMLTag están configurados con los atributos que pueden tener.
Dejo un par o tres para que entiendas a lo que me refiero:
1
2
3
4
5
6
COLUMN(new XMLTag("column")
            .setAttribute("fieldname", null)),
ROW(new XMLTag("row")
            .setAttribute("fieldname", null)),
CELL(new XMLTag("cell")
            .setAttribute("fieldname", null));

Ahora pensando, me he dado cuenta de que para esto que quiero hacer el sistema que he pensado no sirve por varias razones. Una es que las clases que relaciono con las constantes son estáticas, finales y además, por si no fuera suficiente, tienen métodos para modificarlas. Si de caso tendría que añadir otro método que permita realizar una cópia de las XMLTag, pero no. Es un muy mal diseño.

Siempre puedo hacer que las constantes se relacionen con un String, que contenga simplemente el nombre de la tag, pero que pasa con sus atributos?
De tomar este diseño se solventan muchos problemas, pero aparecen otros.
Si quiero darle un valor por defecto a un atributo, (arriba les doy un valor de null por ejemplo) tengo que relacionar cada constante con 2 arrays de String, uno con el nombre de cada uno de los atributos y el otro con sus valores. Cosa que también es un pésimo diseño.


Estoy muy confundido sobre que camino tomar

Oye, y muchas gracias por contestar al post, la verdad es que da mucha seguridad saber que hay gente por ahí dispuesta a ayudar :D


Edit: el switch sobre el que hablo de hacer, se trata de crear una XMLTag y usar el método estático que propongo el el post, a partir de ahí crear un caso para cada una de las posibles constantes que ese método estático pueda retornar.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

enum un poco peculiar

Publicado por juan (43 intervenciones) el 25/09/2018 05:51:28
Son las 6:00 AM, llevo toda la noche tratando de conseguir una solución y no se me ocurre nada que no rompa los fundamentos de la POO.
Voy a adjuntar el código del enum, por si alguien ve algo que yo no, pero creo que no se puede replicar esto a un sistema de clases.
Aquí va el enum:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
@SuppressWarnings("unused")
public enum SQLTags {
 
    STORAGE_MEDIUM("database",
            new String[]{"fieldname", "user", "password"},
            new String[]{null, "root", "123"},
            true),
    TABLE("table",
            new String[]{"fieldname"},
            new String[]{null},
            true),
    COLUMN("column",
            new String[]{"fieldname"},
            new String[]{null},
            true),
    ROW("row",
            new String[]{"fieldname"},
            new String[]{null},
            true),
    CELL("cell" ,
            new String[]{"fieldname"},
            new String[]{null},
            true);
 
    private final String tag;
    private final String[] attributes;
    private final String[] attributesvalues;
    private final boolean haschilds;
 
    SQLTags(String tag, String[] attributes, String[] atributesvalues, boolean haschilds) {
        this.tag = tag;
        this.attributes = attributes;
        this.attributesvalues = atributesvalues;
        this.haschilds = haschilds;
    }
 
    public static SQLTags getTagConstant(String tag) {
        for(SQLTags i:values()) {
            if(i.tag().equals(tag)) return i;
        }
        return null;
    }
 
    public String tag() {
        return tag;
    }
 
    public Map<String, String> getAttributes() {
        Map<String, String> map = new HashMap<>();
        for(int i = 0; i < attributes.length; i++) {
            map.put(attributes[i], attributesvalues[i]);
        }
        return map;
    }
 
    public boolean haschilds() {
        return haschilds;
    }
 
    public boolean hastext() {
        return !haschilds;
    }
}
Las utilidades por las que uso este enum son:
■ Permite tener constantes finales.
■ Permite tener multiples datos, también finales, adjuntos a estas constantes.
■ Los datos adjuntos a las constantes no són pasados por referencia (una constante final y mutable es mala idea).
■ Puedo saber a que constante corresponde una tag.
■ El diseño es fácil de entender.

Y los problemas a los que me enfrento con este enum:
■ No puedo reutilizar sus métodos, por lo que hay que hacer copy/paste, cosa que es horrible con Java.

He tratado de replicarlo con clases usando HashMap y el principal problema al que me he enfrentado es que todas las variables y métodos tienen que ser estáticos, por lo que al no crear una instancia de la clase raiz que implementa los métodos causa que las clases hijas añadan los elementos en el mismo HashMap de la raiz.

¿Porqué no pongo todas las constantes en el mismo enum y listo?
Es una solución buenísima, pero esto añadirá complejidad a los atributos de las tags, debido a que será considerada la misma tag una COLUMN de SQL que una COLUMN de un SpreadSheet. Pese a todo, y pese a lo poco separadas que quedarían las constantes, se añadiría complejidad al prorgama a cambio de una mejor estructura.
Y esta segunda és mi preferencia, por lo que si no cambian las cosas, mañana uniré todos los enum y a ver si me apaño.


Creo que doy el hilo por cerrado,
al final he encontrado yo solito la solución, tras un total de como 7-8 horas para unas constantes de mrd. Aunque lo más importante aquí es que he aprendido un montón y ya sabré que hacer la próxima vez que me pase algo parecido.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar