En los artículos que escribí sobre 23 patrones de diseño, el prefacio es básicamente el mismo, los lectores pueden comenzar a leer desde el Capítulo 2, este artículo trata sobre 工厂方法模式(Factory Method Pattern)
la explicación detallada del patrón de creación.
Directorio de artículos
1. Introducción
Según el libro Design Patterns - Elements of Reusable Object-Oriented Software (traducción al chino: Design Patterns - The Foundation of Reusable Object-Oriented Software), los cuatro autores dividen los patrones de diseño en tres categorías, de la siguiente manera:
1. Patrones de creación
Estos patrones de diseño proporcionan una forma de ocultar la lógica de creación al crear un objeto, en lugar de usar el operador new para instanciar el objeto directamente. Esto hace que el programa sea más flexible para decidir qué objetos deben crearse para una instancia determinada.
- Patrón único
- Patrón de fábrica abstracto
工厂方法模式(Factory Method Pattern)
- Patrón de constructor
- Patrón de prototipo
2. Patrones Estructurales
Estos patrones de diseño se enfocan en la composición de clases y objetos. El concepto de herencia se utiliza para componer interfaces y definir la forma en que los objetos compuestos obtienen nueva funcionalidad.
- Patrón de adaptador
- Patrón de puente
- Patrón compuesto
- Patrón decorador
- Patrón de fachada
- Patrón de peso mosca
- Patrón de representación
3. Patrones de comportamiento
Estos patrones de diseño están particularmente relacionados con la comunicación entre objetos.
- Patrón de cadena de responsabilidad
- Patrón de comando
- Patrón de intérprete
- Patrón de iterador
- Patrón mediador
- Patrón de recuerdo
- Patrón de observador
- Patrón de estado
- Patrón de estrategia
- Patrón de plantilla
- Patrón de visitante
工厂方法模式(Factory Method Pattern)
Este artículo trata sobre la explicación detallada en el modo de creación .
2. Patrón de método de fábrica
2.1 Intención
Defina una interfaz para crear objetos y deje que las subclases decidan qué clase instanciar. Factory Method retrasa la instanciación de una clase a sus subclases.
2.2 Diagrama de clases UML
En el modo de fábrica, no exponemos la lógica de creación al consumidor al crear objetos, y apuntamos al objeto recién creado usando una interfaz común (TeaFactory en la figura a continuación), de la siguiente manera (tome el ahora popular té con leche como un ejemplo):
2.3 Implementación específica del código Java
2.3.1 La estructura del paquete es la siguiente:
2.3.2 paquete de té
public interface Tea {
void make();
}
public class BlackTea implements Tea {
@Override
public void make() {
System.out.println("make the black tea!");
}
}
public class GreenTea implements Tea {
@Override
public void make() {
System.out.println("make the green tea!");
}
}
public class MilkTea implements Tea {
@Override
public void make() {
System.out.println("make the milk tea!");
}
}
2.3.3 paquete de fábrica
/**
* @Author: YuShiwen
* @Date: 2022/2/3 10:43 PM
* @Version: 1.0
*/
public class TeaFactory {
public Tea getTea(String tea) {
if ("blackTea".equalsIgnoreCase(tea)) {
return new BlackTea();
} else if ("greenTea".equalsIgnoreCase(tea)) {
return new GreenTea();
} else if ("milkTea".equalsIgnoreCase(tea)) {
return new MilkTea();
} else {
throw new RuntimeException("其他茶品暂不支持!");
}
}
}
2.3.4paquete principal
public class CustomerDemo {
public static void main(String[] args) {
new TeaFactory().getTea("milktea").make();
new TeaFactory().getTea("blacktea").make();
}
}
2.3.5 Resultados de ejecución
2.4 Ventajas y desventajas
Ventajas:
1. Si una persona que llama quiere crear un objeto, solo necesita saber su nombre.
2. Alta escalabilidad Si desea agregar un producto, solo necesita extender una clase de fábrica.
3. La implementación específica del producto de protección está protegida y la persona que llama solo se preocupa por la interfaz del producto.
Desventajas:
Cada vez que se agrega un producto, se debe agregar una clase específica y una fábrica de implementación de objetos, lo que duplica el número de clases en el sistema, aumenta la complejidad del sistema hasta cierto punto y también aumenta la clase específica del sistema confiar
Recomendación:
como patrón de creación de clases, siempre que sea necesario generar objetos complejos, se puede utilizar el patrón de método de fábrica. Una cosa a tener en cuenta es que los objetos complejos son adecuados para usar el patrón de fábrica, mientras que los objetos simples, especialmente aquellos que solo se pueden crear a través de new, no necesitan usar el patrón de fábrica. Si usa el patrón de fábrica, debe introducir una clase de fábrica, lo que aumentará la complejidad del sistema.
2.5 Aplicación en código fuente
2.5.1 Método Integer.valueOf()
- Integer Proporciona el método estático valueOf() para crear Integer. Entonces, ¿cuál es la diferencia entre este método y escribir new Integer(3) directamente? Observamos el método valueOf():
su ventaja es que valueOf() internamente puede usar new para crear una nueva instancia de Integer, pero también puede devolver directamente una instancia de Integer almacenada en caché. - El número entero predeterminado es el rango de caché de [-128, 127]. También lo descubrimos cuando miramos el código fuente. El límite inferior de low es el int final low = -128, que se fijó al principio; The final int está configurado, pero al principio no ha sido asignado, por lo que podemos configurar los parámetros de tiempo de ejecución configurando los parámetros de java:
java -D java.lang.Integer.IntegerCache.high=1024 TestAutoBoxCache
No es necesario que la persona que llama conozca los detalles de la creación de enteros.
El método de fábrica puede ocultar los detalles de la creación de un producto y no necesariamente crea un producto cada vez, puede devolver un producto almacenado en caché, lo que mejora la velocidad y reduce el consumo de memoria.
2.5.2 Método List.of()
- List.of() es un método proporcionado por Java 9. Este método de fábrica estático acepta parámetros variables y devuelve la interfaz List. Comparado con el método Arrays.asList(), la modificación del arreglo original tiene un efecto en la Lista generada por Arrays.asList, pero no tiene efecto en la Lista generada por List.of.
- El producto obtenido por la persona que llama es siempre la interfaz de Lista y no se preocupa por su tipo real. Incluso si la persona que llama sabe que el tipo real del producto List es java.util.ImmutableCollections$ListN, no lo convierta en una subclase, porque se garantiza que el método de fábrica estático List.of() devolverá una Lista, pero puede modificarse para devolver java.util .ArrayList. Este es el principio de sustitución de Liskov: devolver cualquier subclase que implemente la interfaz puede satisfacer los requisitos del método sin afectar a la persona que llama.
2.5.3MessageDigest.getInstance()方法
Lo mismo es cierto para el método MessageDigest.getInstance(), por ejemplo, podemos MessageDigest.getInstance("MD5");
obtener el algoritmo MD5.
Y en el libro de Java Efectivo, Capítulo 2, Artículo 1 es 用静态工厂方法代替构造器
.
Completado, en la madrugada del cuarto día del nuevo año en 2022.