2009-04-15 22 views
5

Estoy involucrado en este proyecto en el que estamos construyendo un buen código heredado. Tengo una situación particular sobre un gran objeto de frijol java que debe transferirse a través de un cable. Así que mi primer pensamiento fue para que sea inmutable y serializable para hacer el truco .En este punto estoy frente a algunas opciones difíciles: -Creación de objetos inmutables de javabean

  1. Lo ideal sería que yo quiero de alguna manera a generar automáticamente un serializable inmutable, versión de esta clase. No tengo el alcance para refactorizar o alterar esta clase de ninguna manera e i realmente odiaría tener que copiar pegar la clase con un nombre diferente ?

  2. Suponiendo que me di por vencido en 1, es decir i , voluntariamente, a duplicar el código de la clase JavaBean enorme, yo todavía estará en la situación desagradable de tener que escribir un constructor con algunos parámetros 20-25 para hacer esta clase inmutable. ¿Qué es una mejor forma de para hacer una clase inmutable que no sea la inyección de constructor?

Gracias y Saludos,

+0

Esta es una muy buena pregunta. A menos que tengas una clase inmutable duplicada, no parece haber una manera realmente buena de resolver esto. ¡He usado el método efectivamente inmutable! – Fortyrunner

Respuesta

4

para que sea realmente inmutable, es necesario inicializar los miembros en el tiempo de construcción.

Una forma (y no digo que sea bonita) de hacer esto y evitar una gran lista de parámetros en el constructor es tener un tipo mutable que tenga las mismas propiedades. Establezca las propiedades en el tipo mutable de a una por medio de "setters", luego pase el objeto mutable al constructor del tipo inmutable como un único argumento. El objeto inmutable luego copia las propiedades de la fuente mutable a sus propios miembros (final).

También podría considerar "inmutabilidad efectiva". Es decir, aunque el sistema no aplica la inmutabilidad, utiliza prácticas de codificación que separan claramente la fase de inicialización de la fase de uso. Después de todo, la inmutabilidad no es necesaria para la serialización.

Puede llevar esto un paso más allá, creando un contenedor de ocultación de implementación para la interfaz que no expone las propiedades de la implementación. El contenedor solo implementa los métodos en la interfaz, al delegar a la implementación "real". Los setters y getters de la implementación no están presentes en el contenedor. Esto evitará que los clientes simplemente descarguen desde la interfaz a la clase de implementación y manipulen las propiedades.

+0

puede agregar algún ejemplo de código para cada uno de sus escenarios, estoy tratando de comprender y teniendo dificultades. – Rachel

1

20-25 propiedades no es gran cosa para una, especialmente si está utilizando un editor medio decente.

Si ya tiene una instancia mutable al construir la versión inmutable, simplemente páselo al constructor.

Si quieren ser muy mal hacky, utilice java.beans para crear un serialisable Map para la clase o subclase mutable implementar Externalizable. Alternativamente, podría usar la serialización XML java.beans (el XML que se puede enviar a través de la serialización Java ...).

0

Paso 1: Crea una nueva clase y dale variables de instancia con los mismos nombres exactos que las variables de instancia de tu 'gran objeto de Java Bean'. Esa nueva clase no debería tener instaladores (sino solo buscadores) para que sea inmutable.

Paso 2: Use Apache Commons BeanUtils.copyProperties para copiar todas las propiedades (es decir, variables de instancia) de su 'gran objeto bean java' a su nuevo objeto.

0

algunas ideas:

set Protegidas y métodos de fábrica Puede definir los frijoles con métodos setter protegidas y en el mismo paquete, una clase de fábrica que se lleva todos los parámetros y llama las incubadoras. El frijol es inmutable fuera de ese paquete. Para hacer cumplir esto, asegúrese de sellar su jar para que los usuarios finales no puedan crear nuevas clases en el mismo paquete.

Nota: Puede utilizar mis anotaciones JavaDude de frijol para hacer la creación más simple: http://code.google.com/p/javadude/wiki/Annotations

Por ejemplo: captadores

@Bean(writer=Access.PROTECTED, // all setXXX methods will be protected 
    properties={ 
     @Property(name="name"), 
     @Property(name="age", type=int.class) 
    }) 
public class Person extends PersonGen { 
} 

Creación y un constructor en Eclipse

Eclipse tiene algunas buenas herramientas para hacer esto rápido:

  1. crear la clase de frijol
  2. Añadir los campos que desee
  3. Haga clic derecho en la ventana del editor
  4. Elija Fuente-> Generar captadores y definidores
  5. Pulse los captadores "Seleccionar" botón
  6. Press bien
  7. Haga clic derecho en la ventana del editor
  8. Elija Fuente-> Generar constructores de campos
  9. Pico k y ordenar los campos que desee en el constructor
  10. Pulse ok

inmutabilidad decorador

Otra idea es definir su frijol con captadores y definidores (se puede utilizar la técnica anterior sino que incluyen los emisores), entonces puedes crear una clase contenedora que solo tenga los getters.

1

Qué pasa con una sencilla interfaz de sólo lectura cotaining los captadores?

Si la clase de bean es suya, permítale implementarla sencillamente y usar solo la interfaz después de la creación.

Si no tiene control sobre la clase de bean, también puede crear una interfaz getter e implementarla creando un proxy para la interfaz getter con un controlador de invookation delegando todas las llamadas al bean.