El patrón de diseño de fábrica (o método de fábrica) se especializa en delegación y encapsulación. Este patrón permite que una superclase difiera la creación de instancias a las subclases. Esto se debe a que la clase que contiene el patrón del método de fábrica principal es abstracta.
La versión original del método de fábrica asume la forma de un método no implementado porque no conoce el producto que creará. El método de fábrica puede saber que está creando algún producto, pero no conoce las características específicas del producto que creará. Este conocimiento solo está disponible para las respectivas subclases. Por lo tanto, la responsabilidad de implementar el método de fábrica y crear objetos apropiados es únicamente de una subclase.
Implementando el patrón de diseño de fábrica en Java
Este artículo utiliza una aplicación de generación de informes de comentarios de muestra. Esta aplicación utiliza los diferentes tipos de comentarios que recibe una empresa (para un nuevo refrigerio) para crear informes específicos (usando el método de fábrica). Por lo tanto, el patrón de fábrica creará comentarios específicos (o informes de comentarios), utilizando la siguiente clase de producto principal como base:
públicoabstractoclaseComentario{
privado Cadena nombre del revisor;
privado Cadena revisarMensaje;
privadoEn t Calificaciones de revisión;
públicoComentario(String nombre del revisor, String mensaje de revisión, En t reseñaCalificaciones){
este.reviewerName = reviewerName;
este.reviewMessage = revisarMensaje;
este.reviewRatings = reviewRatings;
}
público Cadena getReviewerName(){
devolver nombre del revisor;
}
públicovacíosetReviewerName(String reviewerName){
este.reviewerName = reviewerName;
}
público Cadena getReviewMessage(){
devolver revisarMensaje;
}
públicovacíoestablecerReviewMessage(Cadena de mensaje de revisión){
este.reviewMessage = revisarMensaje;
}
públicoEn tobtenerRevisiónCalificaciones(){
devolver Calificaciones de revisión;
}
públicovacíosetReviewCalificaciones(En t reseñaCalificaciones){
este.reviewRatings = reviewRatings;
}
}
Cada comentario tendrá tres propiedades obligatorias, un nombre de revisor, un mensaje de revisión y una calificación numérica (de uno a cinco) para el nuevo refrigerio. Los diferentes tipos de comentarios que recibirá la empresa provendrán de uno de estos tres canales:
Clase de retroalimentación por correo electrónico
públicoclaseCorreo electrónicoComentariosextiendeComentario{
privado Cadena revisorEmail;
Comentarios de correo electrónico público (Cadena nombre del revisor, Cadena revisiónMensaje, int revisiónCalificaciones, Cadena correo electrónico del revisor) {
súper(reviewerName, reviewMessage, reviewRatings);
este.reviewerEmail = revisorEmail;
}
público Cadena getReviewerEmail(){
devolver revisorEmail;
}
públicovacíosetReviewerCorreo electrónico(Correo electrónico del revisor de cadenas){
este.reviewerEmail = revisorEmail;
}
}
Clase de comentarios por correo
públicoclaseCorreo electrónicoComentariosextiendeComentario{
privado Cadena dirección del remitente;
Comentarios de correo público (Cadena nombre del revisor, Cadena revisiónMensaje, int revisiónCalificaciones, Cadena dirección del remitente) {
súper(reviewerName, reviewMessage, reviewRatings);
este.returnAddress = returnAddress;
}público Cadena getReturnAddress(){
devolver dirección del remitente;
}
públicovacíoestablecerReturnAddress(Cadena dirección de retorno){
este.returnAddress = returnAddress;
}
}
Clase de retroalimentación de redes sociales
públicoclaseSocialMediaComentariosextiendeComentario{
privado Cadena revisorManejador;
Retroalimentación pública de las redes sociales (Cadena nombre del revisor, Cadena revisiónMensaje, int revisiónCalificaciones, Cadena identificador del revisor) {
súper(reviewerName, reviewMessage, reviewRatings);
este.reviewerHandle = revisorHandle;
}
público Cadena getReviewerHandle(){
devolver revisorManejador;
}
públicovacíoestablecerReviewerHandle(Revisor de cadenasHandle){
este.reviewerHandle = revisorHandle;
}
}
Notará que cada subclase de retroalimentación tiene una propiedad única. Esto significa que deberá crear el informe para cada tipo de comentario utilizando al menos una propiedad que sea única para ese tipo.
La fábrica sencilla
Una fábrica simple es un enfoque popular para usar el patrón de diseño de fábrica. Este enfoque implica agrupar todas las diferentes retroalimentaciones (o productos) en un método (la fábrica simple) y seleccionar la retroalimentación adecuada en función de un parámetro.
públicoclaseFeedbackReportFactory{
público Comentario hacerComentarios(Tipo de retroalimentación de cadena){
retroalimentación retroalimentación = nulo;
si(feedbackType.equals("correo electrónico")) {
retroalimentación = nuevo Comentarios por correo electrónico();
}demássi (feedbackType.equals("correo")) {
retroalimentación = nuevo Comentarios de correo ();
}demássi (feedbackType.equals("social")) {
retroalimentación = nuevo Comentarios de las redes sociales();
}
devolver comentario;
}
}
Sin embargo, el enfoque de fábrica simple no es el patrón de diseño de fábrica, ni es un patrón de diseño. Es más como un concepto de diseño.
El método de fábrica
El método de fábrica es la verdadera representación del patrón de diseño. Usando el método de fábrica, el reformado FeedbackReportFactoryclase Java ahora contendrá el siguiente código:
públicoabstractoclaseFeedbackReportFactory{
públicoabstractovacíohacer un informe de retroalimentación(Retroalimentación retroalimentación);
}
Puede definir la estructura del patrón de diseño de fábrica con el siguiente diagrama de clases:
En el diagrama anterior, verá que una clase abstracta (o interfaz) contendrá una versión abstracta del método de fábrica. Entonces, las clases de fábrica concretas que extienden la clase abstracta implementarán el método de fábrica, utilizando propiedades que son únicas para el producto que desea crear. También debe tener en cuenta que cualquier clase de fábrica concreta debe crear uno o más productos.
La aplicación de muestra tiene tres productos relacionados pero únicos. Cada tipo de comentario tiene al menos una propiedad única. Por lo tanto, la aplicación deberá tener tres fábricas concretas para construir cada producto.
Fábrica de comentarios por correo electrónico
públicoclaseInforme de comentarios por correo electrónicoextiendeFeedbackReportFactory{
Retroalimentación por correo electrónico;
@Anular
públicovacíohacer un informe de retroalimentación(Retroalimentación retroalimentación){
este.feedback = (Retroalimentación por correo electrónico) retroalimentación;
Sistema.afuera.println("\nReportarParaComentarioA través deCorreo electrónico" +
"\nNombre del revisor: " +este.feedback.getReviewerName() +
"\nComentarios: " + este.feedback.getReviewMessage() +
"\nCalificaciones: " + este.feedback.getReviewRatings() +
"\nDirección incorrecta: " + este.feedback.getReviewerEmail());
}
}
Fábrica de comentarios de correo
públicoclaseInforme de retroalimentación de correoextiendeFeedbackReportFactory{
retroalimentación de MailFeedback;
@Anular
públicovacíohacer un informe de retroalimentación(Retroalimentación retroalimentación){
este.feedback = (CorreoFeedback) comentarios;
Sistema.afuera.println("\nReportarParaComentarioA través deCorreo" +
"\nNombre del revisor: " +este.feedback.getReviewerName() +
"\nComentarios: " + este.feedback.getReviewMessage() +
"\nCalificaciones: " + este.feedback.getReviewRatings() +
"\nDirección postal: " + este.feedback.getReturnAddress());
}
}
Fábrica de comentarios de redes sociales
públicoclaseInforme de comentarios de redes socialesextiendeFeedbackReportFactory{
Retroalimentación de SocialMediaFeedback;
@Anular
públicovacíohacer un informe de retroalimentación(Retroalimentación retroalimentación){
este.feedback = (SocialMediaFeedback) feedback;
Sistema.afuera.println("\nReportarParaComentarioA través deSocialMedios de comunicación" +
"\nNombre del revisor: " + este.feedback.getReviewerName() +
"\nComentarios: " + este.feedback.getReviewMessage() +
"\nCalificaciones: " + este.feedback.getReviewRatings() +
"\nIdentificador de redes sociales del revisor: " + este.feedback.getReviewerHandle());
}
}
Prueba de la aplicación de muestra
Ahora puedes usar los respectivos métodos de fábrica para hacer informes en miniatura sobre los comentarios recibidos de los diferentes canales. Puede probar la aplicación usando JUnit, o puede crear una clase de controlador:
públicoclasePrincipal{
públicoestáticovacíoprincipal(Cadena[] argumentos){
retroalimentación retroalimentación = nuevo Comentarios por correo electrónico ("Mella", "¡Buen producto!", 5, "[email protected]");
Retroalimentación retroalimentación2 = nuevo Comentarios de correo ("John", "El producto es bueno pero no es algo que compraría regularmente", 4, "primera calle");
Retroalimentación retroalimentación3 = nuevo Comentarios de las redes sociales("Jane", "No es para mi", 2, "@janey");
fábrica de FeedbackReportFactory = nuevo Informe de comentarios de correo electrónico ();
FeedbackReportFactory factory2 = nuevo Informe de retroalimentación de correo ();
FeedbackReportFactory factory3 = nuevo Informe de retroalimentación de redes sociales();
fábrica.makeFeedbackReport(comentario);
fábrica2.makeFeedbackReport(retroalimentación2);
fábrica3.makeFeedbackReport(retroalimentación3);
}
La clase principal anterior usa las fábricas respectivas para crear tres informes, produciendo el siguiente resultado en la consola:
Ventajas de usar el patrón de diseño de fábrica
El patrón de diseño de fábrica promueve la flexibilidad de diseño, donde usa interfaces (o clases abstractas) para crear clases concretas. También promueve la escalabilidad a través del polimorfismo, al permitir que nuevas clases implementen la interfaz existente a medida que se expande la aplicación.
Cuando usa el patrón de diseño de fábrica, está utilizando dos principios de diseño importantes: abierto-cerrado e inversión de control (IoC).