¿Qué es un método de "fábrica estática"?
¿Qué es un método de "fábrica estática"?
Respuestas:
Evitamos proporcionar acceso directo a las conexiones de la base de datos porque requieren muchos recursos. Entonces usamos un método de fábrica estático getDbConnection
que crea una conexión si estamos por debajo del límite. De lo contrario, intenta proporcionar una conexión "libre", fallando con una excepción si no hay ninguna.
public class DbConnection{
private static final int MAX_CONNS = 100;
private static int totalConnections = 0;
private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();
private DbConnection(){
// ...
totalConnections++;
}
public static DbConnection getDbConnection(){
if(totalConnections < MAX_CONNS){
return new DbConnection();
}else if(availableConnections.size() > 0){
DbConnection dbc = availableConnections.iterator().next();
availableConnections.remove(dbc);
return dbc;
}else {
throw new NoDbConnections();
}
}
public static void returnDbConnection(DbConnection dbc){
availableConnections.add(dbc);
//...
}
}
El patrón de método de fábrica estático es una forma de encapsular la creación de objetos. Sin un método de fábrica, sólo tendría que llamar a la clase de constructor directamente: Foo x = new Foo()
. Con este patrón, debe en su lugar llamar al método de fábrica: Foo x = Foo.create()
. Los constructores están marcados como privados, por lo que no se pueden llamar excepto desde dentro de la clase, y el método de fábrica se marca de static
modo que se pueda llamar sin tener primero un objeto.
Hay algunas ventajas en este patrón. Una es que la fábrica puede elegir entre muchas subclases (o implementadores de una interfaz) y devolver eso. De esta manera, la persona que llama puede especificar el comportamiento deseado a través de parámetros, sin tener que conocer o comprender una jerarquía de clases potencialmente compleja.
Otra ventaja es, como han señalado Matthew y James, controlar el acceso a un recurso limitado como las conexiones. Esta es una forma de implementar grupos de objetos reutilizables : en lugar de construir, usar y derribar un objeto, si la construcción y la destrucción son procesos costosos, podría tener más sentido construirlos una vez y reciclarlos. El método de fábrica puede devolver un objeto instanciado existente sin usar si tiene uno, o construir uno si el recuento de objetos está por debajo de un umbral inferior, o lanzar una excepción o devolver null
si está por encima del umbral superior.
Según el artículo en Wikipedia, los múltiples métodos de fábrica también permiten diferentes interpretaciones de tipos de argumentos similares. Normalmente, el constructor tiene el mismo nombre que la clase, lo que significa que solo puede tener un constructor con una firma determinada . Las fábricas no están tan restringidas, lo que significa que puede tener dos métodos diferentes que aceptan los mismos tipos de argumentos:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
y
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
Esto también se puede utilizar para mejorar la legibilidad, como señala Rasmus.
¡NOTA! "El método de fábrica estático NO es el mismo que el patrón de Método de fábrica " (c) Java efectivo, Joshua Bloch.
Método Factory: "Defina una interfaz para crear un objeto, pero deje que las clases que implementan la interfaz decidan qué clase instanciará. El método Factory permite que una clase difiera la instanciación a las subclases" (c) GoF.
"El método de fábrica estático es simplemente un método estático que devuelve una instancia de una clase". (c) Efectivo Java, Joshua Bloch. Por lo general, este método está dentro de una clase particular.
La diferencia:
La idea clave del método de fábrica estática es obtener control sobre la creación de objetos y delegarlo del constructor al método estático. La decisión del objeto a crear es como en Abstract Factory hecha fuera del método (en el caso común, pero no siempre). Si bien la idea clave (!) Del Método Factory es delegar la decisión de qué instancia de clase crear dentro del Método Factory. Por ejemplo, la implementación clásica de Singleton es un caso especial del método estático de fábrica. Ejemplo de métodos de fábrica estáticos comúnmente utilizados:
La legibilidad se puede mejorar mediante métodos estáticos de fábrica:
Comparar
public class Foo{
public Foo(boolean withBar){
//...
}
}
//...
// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.
a
public class Foo{
public static Foo createWithBar(){
//...
}
public static Foo createWithoutBar(){
//...
}
}
// ...
// This is much easier to read!
Foo foo = Foo.createWithBar();
private Foo(boolean withBar){/*..*/}
public static Foo createWithBar(){return new Foo(true);}
public static Foo createWithoutBar(){return new Foo(false);}
- tener nombres, a diferencia de los constructores, que pueden aclarar el código.
- no es necesario crear un nuevo objeto en cada invocación; los objetos se pueden almacenar en caché y reutilizar, si es necesario.
- puede devolver un subtipo de su tipo de retorno; en particular, puede devolver un objeto cuya clase de implementación es desconocida para el llamante. Esta es una característica muy valiosa y ampliamente utilizada en muchos marcos que utilizan interfaces como el tipo de retorno de los métodos estáticos de fábrica.
Todo se reduce a la mantenibilidad. La mejor manera de decir esto es que cuando usa la new
palabra clave para crear un objeto, está acoplando el código que está escribiendo en una implementación.
El patrón de fábrica le permite separar cómo crea un objeto de lo que hace con el objeto. Cuando crea todos sus objetos usando constructores, esencialmente está cableando el código que usa el objeto para esa implementación. El código que usa su objeto es "dependiente de" ese objeto. Puede que esto no parezca un gran problema en la superficie, pero cuando el objeto cambia (piense en cambiar la firma del constructor o subclasificar el objeto) debe retroceder y volver a cablear las cosas en todas partes.
Hoy en día, las fábricas han sido descartadas en gran medida a favor del uso de la inyección de dependencia porque requieren una gran cantidad de código de placa de caldera que resulta un poco difícil de mantener. La inyección de dependencia es básicamente equivalente a las fábricas, pero le permite especificar cómo sus objetos se conectan entre sí de forma declarativa (a través de la configuración o anotaciones).
Si el constructor de una clase es privado, no puede crear un objeto para la clase desde fuera de ella.
class Test{
int x, y;
private Test(){
.......
.......
}
}
No podemos crear un objeto para la clase anterior desde fuera de ella. Por lo tanto, no puede acceder a x, y desde fuera de la clase. Entonces, ¿de qué sirve esta clase?
Aquí está la respuesta: método de FÁBRICA .
Agregue el siguiente método en la clase anterior
public static Test getObject(){
return new Test();
}
Entonces ahora puede crear un objeto para esta clase desde fuera de ella. De esa manera...
Test t = Test.getObject();
Por lo tanto, un método estático que devuelve el objeto de la clase ejecutando su constructor privado se llama método FACTORY
.
Static Factory Method
sobre el constructor público?
Pensé que agregaría algo de luz a esta publicación sobre lo que sé. Utilizamos esta técnica ampliamente en nuestro recent android project
. En lugar de creating objects using new operator
usted, también puede usar static method
para crear una instancia de una clase. Listado de código:
//instantiating a class using constructor
Vinoth vin = new Vinoth();
//instantiating the class using static method
Class Vinoth{
private Vinoth(){
}
// factory method to instantiate the class
public static Vinoth getInstance(){
if(someCondition)
return new Vinoth();
}
}
Los métodos estáticos admiten la creación de objetos condicionales : cada vez que invoque un constructor, se creará un objeto, pero es posible que no lo desee. suponga que desea verificar alguna condición solo entonces desea crear un nuevo objeto. No crearía una nueva instancia de Vinoth cada vez, a menos que su condición se cumpla.
Otro ejemplo tomado de Effective Java .
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Este método traduce un valor primitivo booleano en una referencia de objeto booleano. El Boolean.valueOf(boolean)
método nos ilustra, nunca crea un objeto. La capacidad de static factory methods
devolver el mismo objeto de repetido invocations
permite a las clases mantener un control estricto sobre qué instancias existen en cualquier momento.
Static factory methods
es que, a diferencia constructors
, que puede devolver una object
de cualquier subtype
de su tipo de retorno. Una aplicación de esta flexibilidad es que una API puede devolver objetos sin hacer públicas sus clases. Ocultar clases de implementación de esta manera conduce a una API muy compacta.
Calendar.getInstance () es un gran ejemplo para lo anterior, se crea según la configuración regional a BuddhistCalendar
, JapaneseImperialCalendar
o por defecto Georgian
.
Otro ejemplo que podría pensar es Singleton pattern
, cuando haces que tus constructores sean privados, crea un getInstance
método propio donde te aseguras de que siempre haya una sola instancia disponible.
public class Singleton{
//initailzed during class loading
private static final Singleton INSTANCE = new Singleton();
//to prevent creating another instance of Singleton
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}
Un método de fábrica un método que abstrae la creación de instancias de un objeto. En general, las fábricas son útiles cuando sabe que necesita una nueva instancia de una clase que implemente alguna interfaz pero no conoce la clase de implementación.
Esto es útil cuando se trabaja con jerarquías de clases relacionadas, un buen ejemplo de esto sería un kit de herramientas GUI. Simplemente podría codificar las llamadas a los constructores para implementaciones concretas de cada widget, pero si alguna vez quisiera cambiar un kit de herramientas por otro, tendría muchos lugares para cambiar. Al usar una fábrica, reduce la cantidad de código que necesitaría cambiar.
Una de las ventajas que se deriva de la fábrica estática es que esa API puede devolver objetos sin hacer públicas sus clases. Esto condujo a una API muy compacta. En java, esto se logra mediante la clase Collections, que oculta alrededor de 32 clases, lo que hace que la colección API sea muy compacta.
Un método de fábrica estático es bueno cuando desea asegurarse de que solo una instancia única devolverá la clase concreta que se utilizará.
Por ejemplo, en una clase de conexión de base de datos, es posible que desee que solo una clase cree la conexión de la base de datos, de modo que si decide cambiar de Mysql a Oracle puede cambiar la lógica en una clase, y el resto de la aplicación lo hará usa la nueva conexión.
Si desea implementar la agrupación de bases de datos, eso también se haría sin afectar el resto de la aplicación.
Protege el resto de la aplicación de los cambios que puede realizar en la fábrica, que es el propósito.
La razón por la que es estática es si desea realizar un seguimiento de algunos recursos limitados (número de conexiones de socket o identificadores de archivos), entonces esta clase puede realizar un seguimiento de cuántos se han pasado y devuelto, por lo que no agota el recurso limitado
Una de las ventajas de los métodos de fábrica estáticos con constructor privado (la creación de objetos debe haber sido restringida para clases externas para garantizar que las instancias no se creen externamente) es que puede crear clases controladas por instancias . Y las clases controladas por instancia garantizan que no existan dos instancias distintas iguales ( a.equals (b) si y solo si a == b ) durante la ejecución de su programa, eso significa que puede verificar la igualdad de objetos con el operador == en lugar del método igual , según Effective java.
La capacidad de los métodos de fábrica estáticos para devolver el mismo objeto de invocaciones repetidas permite a las clases mantener un control estricto sobre qué instancias existen en cualquier momento. Se dice que las clases que hacen esto están controladas por instancia. Hay varias razones para escribir clases controladas por instancia. El control de instancia permite que una clase garantice que es un singleton (Elemento 3) o no instantable (Elemento 4). Además, permite que una clase inmutable (Elemento 15) garantice que no existen dos instancias iguales: a.equals (b) si y solo si a == b. Si una clase hace esta garantía, sus clientes pueden usar el operador == en lugar del método igual (Objeto), lo que puede mejorar el rendimiento. Los tipos de enumeración (Artículo 30) proporcionan esta garantía.
De Java efectivo, Joshua Bloch (artículo 1, página 6)
estático
Un miembro declarado con la palabra clave 'static'.
métodos de fábrica
Métodos que crean y devuelven nuevos objetos.
en Java
El lenguaje de programación es relevante para el significado de 'estático' pero no para la definición de 'fábrica'.
La implementación de Java contiene las clases de utilidades java.util.Arrays y java.util.Collections, ambas contienen métodos estáticos de fábrica , ejemplos de esto y cómo usarlo:
Arrays.asList("1","2","3")
Collections.synchronizedList(..), Collections.emptyList(), Collections.unmodifiableList(...)
(Solo algunos ejemplos, podrían verificar javadocs para ver ejemplos de métodos mor https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html )
También la clase java.lang.String tiene métodos de fábrica estáticos :
String.format(...), String.valueOf(..), String.copyValueOf(...)