2012-04-24 8 views
10

Según el código de limpieza de Robert C. Martin los métodos deben tener una firma pequeña. El mejor caso sería un método sin parámetros en absoluto. En su lugar, se recomienda utilizar variables de estado. Esto es realmente útil. Pero, ¿qué pasa con los beans de sesión sin estado?Código de limpieza, beans de sesión sin estado y estado privado

El nombre es algo confuso porque SLSB puede tener estado. Solo tiene que hacer su mantenimiento para que no use el estado de la llamada EJB anterior.

Volviendo al código de limpieza: me encantaría usar variables de instancia en SLSB también. Esto funciona bien y, si eres lo suficientemente cuidadoso, no tienes problemas con las inconsistencias de estado ya que el estado se sobrescribe en cada llamada a método público.

Hasta ahora todo bien. Pero, ¿qué sucede si un frijol usado vuelve a la piscina? Toma su estado con eso. Dependiendo del tamaño del estado, esto podría ser una pérdida de memoria real. JBoss es muy generoso con los frijoles y genera bastantes de ellos que causan un consumo de memoria importante, en vano.

De modo que una forma sería limpiar el estado antes de que exista el método de bean y el bean se devuelva al grupo. Pero esto me parece un código inútil que debería evitarse.

¿Hay una forma adecuada de solucionar este problema? ¿Cuál es la mejor práctica en esta situación?

+0

Cualquier estado mantenido por algún método de bricolaje fallará ante la agrupación, por lo que no es bienvenido para JEE. Y mantener una copia de ese estado para cada frijol también me parece incorrecto. –

Respuesta

0

Mantenga la vida simple, solo ingrese los parámetros. Incluso si puede hacer lo contrario, es obvio por la intención de un EJB sin estado que no debería.

FWIW con el objetivo de un objetivo de cero parámetros me parece tonto. Objetivo para pocos, sí, pero luchar por cero por sí mismo es simplemente tonto.

+0

En realidad, soy muy dogmático sobre los métodos de cero parámetros. Pero me gusta usar un máximo de 2 parámetros. Encuentro métodos con más de dos parámetros más difíciles de leer y mantener. Y desde el modelo OO, tiene sentido usar variables de estado si la cohesión es alta. –

+1

Eso está muy bien, pero dando un paso atrás, reconozcamos que está hablando de poner preferencia cosmética personal contra * agregar estado * a lo que es claramente un * frijol sin estado *. Debe equilibrar los principios OO con esto, no solo favorecerlos a ciegas. – Brian

+0

Por cierto, un voto a la baja parece duro en respuesta a una opinión genuina que simplemente no concuerda con la dirección en la que parece querer tomar su grano de café. – Brian

0

según el código de limpieza por métodos de Robert C. Martin debe tener una pequeña firma .

Normalmente preferiría pasar (transferir objetos) como argumentos, de esta manera puedo cambiar lo que paso sin afectar la firma del método.

Además, preferiría pasar en una interfaz, en lugar de la clase base real.

public void doSomething(IMyTransferObject arg){ 
... 
} 

Dónde IMyTransferObject es una interfaz

interface IMyTransferObject { 
    ... 
} 

class TransferObject implements IMyTransferObject{ 
    private String name; 
    private String game; 
    ... accessor/mutator 
} 

El mejor caso sería un método sin parámetros en todos. En su lugar, se recomienda para usar variables de estado. Esto es realmente útil. Pero ¿qué ocurre con los beans de sesión sin estado?

Esto no se puede seguir religiosamente, y no hay ninguna razón para hacerlo realmente.

+0

Eso es un montón de código para los métodos privados internos :) En realidad, estaba hablando de los métodos privados dentro de SLSB. –

0

De http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html:

Frijoles

sin estado de sesión

Una sesión de bean sin estado no mantiene un estado de conversación con el cliente. Cuando un cliente invoca los métodos de un bean sin estado, las variables de instancia del bean pueden contener un estado específico de ese cliente, pero solo durante la invocación . Cuando se finaliza el método, no se debe retener el estado específico del cliente . Los clientes pueden, sin embargo, cambiar el estado de las variables de instancia en beans sin estado agrupados, y este estado se mantiene en la siguiente invocación del bean sin estado agrupado. Excepto durante la invocación del método, todas las instancias de un bean sin estado son equivalentes, lo que permite que el contenedor EJB asigne una instancia a cualquier cliente . Es decir, el estado de un bean de sesión sin estado debe aplicarse en todos los clientes.

No soy un experto en EE, pero me parece que técnicamente está permitido usar campos de la forma en que usted planifica también.

Asumo que tiene para asegurarse de que con cada nueva llamada al método, los campos de instancia se actualizan con los nuevos datos, y creo que debe asegurarse de que está eliminando las referencias después de que el método ha terminado para asegurarse de no bloquear la recolección de basura de objetos viejos simplemente porque están referenciados en algún bean "viejo" que todavía se mantiene en algún grupo.

que sugeriría un patrón de esa manera:

public class MyBean{ 

    private SomeClass firstObject; 
    private SomeOtherClass anotherObject; 
    private AndAnotherClass thirdObject; 

    public void theMethod(firstObject, anotherObject, thirdObject){ 
    try { 
     this.firstObject = firstObject; 
     this.anotherObject = anotherObject; 
     this.third = thirdObject; 

     startProcessing(); 

    }finally { 
     this.firstObject = null; 
     this.anotherObject = null; 
     this.third = null; 
    } 
    } 

    private void startProcessing() { 
    doStep1(); 
    doStep2(); 
    doStep3(); 
    } 

    [...] 
} 

Todavía una gran cantidad de código - pero si usted se pega constantemente a ese estilo, se salta automáticamente la parte "theMethod" y continuar la lectura en "startProcessing", donde tienes todo limpiamente y sin parámetros.

0

Es posible mantener las variables de instancia en SLSB, ya que no utiliza el proxy hacer llamadas entre métodos. Por ejemplo:

@Stateless 
public class MyEJB { 
    private String var; 

    public void receiveVar(String var) { 
     this.var = var; 
     useVar(); 
    } 

    private void useVar() { 
     // do something with var 
    } 
} 

El punto es: cuando se inyecta esta SLSB en otro, cualquier llamada al método pasará a través del proxy para lograr el EJB real. Por lo tanto, teniendo en cuenta que la instancia real se recupera del grupo cuando se llama al método en la instancia de proxy, no hay garantía de que el proxy use la misma instancia agrupada entre dos o más llamadas. Por lo tanto, no es posible garantizar el valor de ningún atributo de clase declarado.

Cuando SLSB retrocede al grupo, lleva consigo cada valor establecido (creo que puede cambiar según el proveedor, no estoy seguro). Pero, es completamente posible (y aceptable) que una instancia de SLSB agrupada ya tenga un valor de atributo previamente configurado.

no entendía su punto aquí:

Hasta aquí todo bien. Pero, ¿qué sucede si un frijol usado vuelve a la piscina? Lleva su estado con él. Dependiendo del tamaño del estado, este podría ser una pérdida de memoria real.JBoss es muy generoso con los frijoles y genera un montón de ellos causando un consumo grave de memoria - por nada.

¿Tiene algún ejemplo de "estado grande" que podría tener en un SLSB?

Y, por último:

Creo que la mejor manera de manejar los valores siempre se manejar variables de estado que se va a utilizar. Configuración antes y limpieza después del uso. Y la mejor práctica es evitar este tipo de situación confusa.

Espero que ayude.

Cuestiones relacionadas