2010-12-16 25 views
5
class MyThing { 
    protected HashMap<String,Object> fields; 

    protected MyThing(HashMap<String,Object> newFields){ 
     fields.putAll(newFields); 
    } 

    protected Object get(String key){ 
     return fields.get(key); 
    } 
} 

Ahora un poco de historia. Estoy usando esta clase como una súper clase para un grupo de diferentes clases que representan objetos de un archivo XML. Esto es básicamente una implementación de un contenedor de API y lo estoy usando como un adaptador entre el XML analizado de una API y una base de datos. Casting se delega a la persona que llama del método get. Si las subclases necesitan hacer algo cuando se crean o cuando devuelven una variable, simplemente llaman a super y luego manipulan lo que se devuelve después. ej .:Usar una clase contenedora sin tipo alrededor de objetos almacenados en XML, ¿es malo?

class Event extends MyThing {  
    public Event(HashMap<String,Object> newFields){ 
     super(newFields); 

     // Removes anything after an @ symbol in returned data 
     Pattern p = Pattern.compile("\\@.*$"); 
     Matcher m = p.matcher((String)fields.get("id")); 
     boolean result = m.find(); 

     if (result) 
      fields.put("id", m.replaceFirst("")); 
     } 
    } 

    public Object get(String key){ 
     Object obj = super(key); 

     if (key.equals("name")){ 
      return "Mr./Mrs. " + ((String)obj); 
     } 
    } 
} 

La razón por la que siento que debería hacer esto es por lo que no tengo que escribir getId, getNombre, métodos getWhatever para cada subclase sólo porque tienen diferentes atributos. Ahorraría tiempo y es bastante auto explicativo.

Ahora bien, esto es obviamente "unJavalike" y más como una forma de hacer lenguaje en forma de pato, pero ¿hay alguna razón lógica por la que no debería estar haciendo esto?

+0

¿Por qué no escribes los métodos getString, getInt, ...? – thejh

+0

No hay nada intrínsecamente incorrecto con esto (imo). Mientras los usuarios de la subclase sepan que solo colocan ciertos objetos en su clase, no hay nada de malo en que los arrojen a la salida. – Falmarri

+1

Cambié un poco el título, veo si todavía se adapta a tu intención. : D –

Respuesta

2
  1. Obviamente, no es seguro.
  2. Los futuros mantenedores no sabrán qué tipos se supone que son y generalmente se confundirán con por qué no está utilizando POJO.
  3. En lugar del tiempo constante, la complejidad del espacio y el rendimiento, tiene las características de un HashMap.
  4. Se vuelve muy difícil escribir getters/setters no triviales en el futuro.
  5. La mayoría de los sistemas de enlace de datos están diseñados para funcionar con POJO/Beans (JAXB, JPA, Jackson, etc.).

Estoy seguro de que hay más, pero esto servirá. Intenta usar algunas librerías OXM apropiadas y estarás mucho mejor.

3

Si va a este nivel de complejidad y arruina su modelo de objetos simplemente porque no desea tener getters y setters, hágalo en Groovy.

Groovy es un lenguaje dinámico tipado en pato en la JVM que acepta el 98% del código Java válido, por lo que ya conoce la mayoría del lenguaje (no pierde funcionalidad) ... hay formas "más idiomáticas" de haciendo cosas, pero puedes recogerlas con el tiempo. También ya tiene incorporado XmlSlurper, que probablemente haga la mayor parte de lo que intenta hacer de todos modos.

En cuanto a las "razones por las que no debería", está presentando todo tipo de inquietudes de mantenimiento.

  1. Las nuevas clases siempre tendrán que derivar de la clase base.
  2. Tendrán que implementar un constructor que siempre llame a un constructor base
  3. Tendrán que reemplazar get() [que básicamente está utilizando para encapsular sus getters y setters de todos modos, ¿por qué no simplemente agrega ese método y delega a esos otros métodos] y escribir lógica específica que probablemente se degradará con el tiempo.

¿Por qué no? Funcionará, ¿verdad? Por supuesto. Pero es una ingeniería deficiente en el sentido de que estás creando una pesadilla de mantenimiento o reinventando la rueda y probablemente haciéndolo mal.

+0

Me gusta tu respuesta. Sin embargo, un par de problemas: Groovy no es una opción para mí. Este script se pasará para uso futuro y dudo mucho que quieran aprender la nueva sintaxis de Groovy. Además, ¿funcionaría en una JVM normal sin Groovy instalado en un servidor u otra máquina? Porque no puedo decirlo. En cuanto a "Las nuevas clases siempre tendrán que derivarse de la clase base". - No estoy seguro de por qué eso es un problema. "Tendrán que implementar un constructor que siempre llame a un constructor base" - Tendrán que escribir su propio constructor sin importar qué. y ... – AndrewKS

+0

Para 3. Tendré que escribir getters y setters para todo si lo hago de la forma Java normal, de todos modos. Pero en su lugar, se llenarán con la sintaxis pública getId() {return id;}, public getName() {return name;} una y otra vez para varias clases diferentes. Básicamente es código repetido. – AndrewKS

Cuestiones relacionadas