source pattern method making java factory-pattern public-method

java - method - factory pattern uml



método público de fábrica estática (5)

La clase de un objeto devuelto por el método de fábrica estática no es pública.

Con frecuencia, un método de fábrica estático devolverá un objeto escrito como interfaz (el más común) o, a veces, alguna clase base (menos común). En cualquier caso, no conoce la clase exacta del objeto devuelto.

La ventaja de esto es que obtiene un objeto cuyo comportamiento conoce sin preocuparse por los detalles desordenados de la clase que instancia.

a diferencia de los constructores, los métodos de fábrica estáticos no son necesarios para crear un nuevo objeto cada vez que se invocan

Para entender esto, considere el caso de trabajar con un singleton. Puede llamar a .getInstance () en algunas clases de fábrica para obtener la instancia singleton de un determinado objeto. Normalmente, lo que esto hace es crear una instancia del objeto si no existe, o darle la instancia existente si ya existe. En cualquier caso, usted obtiene una copia del objeto. Pero usted no sabe (y no sabrá) si este singleton tuvo que ser creado, o si uno ya había sido construido previamente.

La ventaja de esto es que el ciclo de vida del objeto y cuando se crea es administrado por usted.

En primer lugar, por favor, perdóneme si es una pregunta realmente tonta, solo estoy tratando de aprender este lenguaje en su esencia. Estoy leyendo Eficaz Java y el primer capítulo habla sobre los métodos de fábrica estáticos frente a los constructores. Sus pros y sus contras. Pocas cosas que me confunden son:

  1. la clase de un objeto devuelto por el método de fábrica estática no es pública : ¿qué significa exactamente?
  2. a diferencia de los constructores, los métodos de fábrica estáticos no son necesarios para crear un nuevo objeto cada vez que se invocan . ¿Cómo sucede esto? ¿Estoy invocando el método de fábrica solo para obtener un nuevo objeto y ponemos un método de verificación en fábrica para verificar si el objeto ya existe?

Gracias.


la clase de un objeto devuelto por el método de fábrica estática no es pública: ¿qué significa exactamente?

Esto significa que la clase real de los objetos devueltos por un método de fábrica estática puede ser una subclase del tipo declarado, y esta subclase no tiene que ser pública. Es solo otro detalle de la implementación que el código del cliente no debería importar.

a diferencia de los constructores, los métodos de fábrica estática no son necesarios para crear un nuevo objeto cada vez que se invocan. ¿Cómo sucede esto? ¿Estoy invocando el método de fábrica solo para obtener un nuevo objeto y ponemos un método de verificación en fábrica para verificar si el objeto ya existe?

Sí, esa es una forma en que esto podría hacerse. Pero en realidad, todo es posible.


Cuando utiliza la new palabra clave, usted como desarrollador sabe que el JDK creará una nueva instancia de ese objeto. Lo que dice el autor, cuando utiliza un método estático, el desarrollador ya no sabe si el método está creando una nueva instancia o posiblemente haciendo otra cosa. Otra cosa puede ser, reutilizar datos en caché, agrupar objetos, crear una implementación privada y devolver una subclase de la clase.


En primer lugar, felicitaciones a usted por su elección en Java-lit: el libro de Bloch es un excelente manual.

Para responder a su segunda pregunta ("a diferencia de los constructores, los métodos de fábrica estática no son necesarios para crear un nuevo objeto cada vez que se invocan"), es importante darse cuenta de que lo que Bloch está diciendo aquí es que con una fábrica estática tiene la opción de : devolver un objeto nuevo o devolver uno preexistente. Todo depende de lo que quieras hacer.

Por ejemplo, supongamos que tiene una clase de valor realmente simple de tipo Money. El método estático de fábrica probablemente debería devolver una nueva instancia, es decir, un nuevo objeto con un valor específico para Money. Entonces, así:

public class Money { private Money(String amount) { ... } /* Note the ''private''-constructor */ public static Money newInstance(String amount) { return new Money(amount); } }

Pero digamos que tiene algún objeto que administra algún recurso y desea sincronizar el acceso a ese recurso a través de alguna clase de ResourceManager. En ese caso, es probable que desee que el método de fábrica estática devuelva la misma instancia de sí mismo a todos, lo que obliga a todos a pasar por la misma instancia, de modo que esa instancia pueda controlar el proceso. Esto sigue el patrón de singleton. Algo como esto:

public ResourceManager { private final static ResourceManager me = new ResourceManager(); private ResourceManager() { ... } /* Note the ''private''-constructor */ public static ResourceManager getSingleton() { return ResourceManager.me; } }

El método anterior obliga a su usuario a que solo pueda usar una sola instancia, lo que le permite controlar con precisión quién (y cuándo) tiene acceso a lo que esté administrando.

Para responder a su primera pregunta, considere esto (es cierto que no es el mejor ejemplo, es bastante ad-hoc):

public class Money { private Money(String amount) { ... } public static Money getLocalizedMoney( MoneyType localizedMoneyType, String amount ) { switch( localizedMoneyType ) { case MoneyType.US: return new Money_US( amount ); case MoneyType.BR: return new Money_BR( amount ); default: return new Money_US( amount ); } } } public class Money_US extends Money { ... } public class Money_BR extends Money { ... }

Note como ahora puedo hacer esto:

Money money = Money.getLocalizedMoney( user_selected_money_type ); saveLocalizedMoney( money );

Nuevamente, un ejemplo realmente artificial, pero espero que le ayude a ver más o menos lo que Bloch estaba tratando de entender con ese punto.

Las otras respuestas fueron buenas: solo pienso que, como principiante, a veces ayuda ver un código real.


Puede responder a ambas preguntas observando un código que hace uso de estas dos propiedades de los métodos de fábrica estáticos. Sugiero mirar en la lista ImmutableList de ImmutableList .

Observe cómo el método of() fábrica no-arg of() siempre devuelve la misma instancia (no crea una nueva instancia cada vez). Si observa detenidamente, también notará que su método de fábrica copyOf(Iterable) realidad devuelve el objeto que se le pasa si ese objeto es en sí mismo una lista de ImmutableList . Ambos están aprovechando el hecho de que se garantiza que una lista ImmutableList nunca cambiará.

Observe también cómo varios métodos de fábrica en él devuelven diferentes subclases, como EmptyImmutableList , SingletonImmutableList y RegularImmutableList , sin exponer los tipos de esos objetos. Las firmas del método solo muestran que devuelven ImmutableList , y todas las subclases de ImmutableList tienen visibilidad de paquete privado (predeterminado), haciéndolas invisibles para los usuarios de la biblioteca. Esto brinda todas las ventajas de las múltiples clases de implementación sin agregar ninguna complejidad desde la perspectiva del usuario, ya que solo se les permite ver ImmutableList como un solo tipo.

Además de ImmutableList , la mayoría de las clases instanciables en Guava utilizan métodos de fábrica estáticos. La guayaba también ejemplifica muchos de los principios establecidos en Effective Java (no es sorprendente, dado que fue diseñado por esos principios y con la guía del propio Josh Bloch), por lo que puede que le resulte útil echarle un vistazo más a medida que lo hace. re trabajando a través del libro.