Te digo algo muy sencillo: De todo lo que he buscado para entender el tema, eres el único que lo ha sabido explicar bien, el resto de videos que he visto hablan pura basura y no explican bien cómo funciona... Excelente... Saludos
Hoy en un proyecto que estoy trabajando, me di cuenta que necesitaba una fábrica porque cambio a cada rato de base de datos y sería bueno pasarle un String por variable de entorno, un video muy útil! Gracias 😄
Genial, explicado con ejemplos de códigos y gráficos. De manera fácil, sencilla y clara. Da gusto aprender así. Mi enhorabuena y sobretodo gracias por tratar un tema tan poco tratado por otros canales pero de tanta importancia como son los Patrones de Diseño
Ayer me queme la cabeza por dos horas buscando una explicación coherente.... y hoy, a mitad de tu video, ya entendia como funcionaba. Suscribo. Edit: es curioso, pero creó q es mas fácil de explicar, en parte, porque la clase Factory del ejemplo no respeta él segundo principio SOLID. La mayoría de los ejemplos ya lo implementaban pero se volvia complejo a la vista. Una buena decisión ahí.
Buenisimo, es genial que cambies los nombres que se usan en ingles a español y contextualizar con ejemplos, eso hace que todo sea mucho mas facil de entender bro! asi que tome su buen like señor programador.
Parabéns, didática muito clara. A desvantagem que eu vejo no padrão Fábrica, é a necessidade de alterar o Shape quando surgirem novas implementações, ele não trabalha de maneira extensiva, ou seja, a classe está aberta para modificação e fechada para extensão, algo que vai de encontro ao princípio SOLID.
Es de locos... Recién empiezo con esto de los patrones y tanto Singleton como Factory los implemente sin darme cuenta. Tenia un problema para un juego RPG por turno que estoy tratando de terminar y se me ocurrió hacer una interfaz para las Acciones (ataque, defensa, cargar y huir) y también hice una clase con un metodo estático, que es la que ejecuta la acción, acorde a lo que el usuario elija, recibiendo como parametro un int, los cuales fije constantes para el tipo de acción, en base a eso... Lo único, mi "factoria" la hice con switch.
Mito explicas excelente!! del ejemplo que nos regalas, en la clase ConexionFabrica reemplazaria los elseif por un switch para evitar el codigo espagueti, de resto todo perfecto
Recuerdo haber visto tu canal hace muchos años atrás (al menos 4 años), y en ese entonces no me pareció un buen canal. Creo que hoy debo reconocer que has mejorado muchísimo en cuanto a la generación de contenido. Muy buenos tutoriales, muy claros, gracias por el trabajo y el tiempo invertido bro!
Según un texto sobre la convención de nombres de java, que si no mal recuerdo era de la misma Oracle, cada palabra debe empezar con mayúscula y luego seguir con solo minúsculas (típico camel case). Esto es cierto incluso para aquellas palabras que son iniciales o siglas con algún significado. Por ejemplo: sedeDeLaONU -> incorrecto sedeDeLaOnu -> correcto El texto también indicaba que están consientes de que la propia API estándar de java rompe dicha convención en ocasiones, pero al parecer solo se mantienen esos nombres irregulares por compatibilidad hacia atrás. Por lo tanto, la forma correcta sería: ComexionMySql, MongoDb, IdPersona, etc...
Se agradece profundamente tu dedicación para estos cursos. Me da la sensación que lo que se explica en este video según lo que he podido ver hoy es un un Simple Idiom Factory, ya que tu código sigue dependiendo de un hardcode en la fábrica por medio de EqualsIgnoreCase, lo que viola el principio SOLID de Open Close. En otros lados he visto que para evitar esto generan una clase abstracta cuyo método abstracto debe ser sobrescrito en las clases que hereden de esta en cuyo interior estan los métodos ya implementados de la Interfaz.
Verdade, fiz um comentário sobre isso. Apesar que, em caso de uma nova implementação, somente a Fábrica seria modificada, ou seja, tem a única responsabilidade de prover implementações. Mas realmente, não está extensível
maginifico, solo un pequeño inciso, crees que estaria bien que en vez de crear todos esos condicionales en la funcion getConexion, quitarlos y poner un array asociativo y retornarlo directamente? o no.Muchas graicas por el aporte
Factory más que ser usado para que solo regrese una instancia, para lo que se usa es para construir objetos con una larga cantidad de parámetro en el constructor
se me ocurre otro contexto donde puede ser útil este patron, por ejemplo para la programación de un juego, instanciar por medio de la fabrica ciertos enemigos que eventualmente cuando destruyas se borraran automaticamente
Muy bien la explicacion, pero creo que hubiera sido mejor que coincida el ejemplo que usaste en codigo (conexion a bases de datos) y el del diagrama (formas geometricas)
Las implementaciones deben sobrescribir los métodos de la interfaz, así no los usen. Las interfaces obligan a las clases que las implementan a que usen esos métodos. De eso se trata una interfaz, de crear una estructura que sea de uso obligatorio para quien lo implemente
El patrón Fábrica solo es aplicable en clases que no requieran parámetros en su constructor?. Por ejemplo si tengo un modelo Clientes y este requiere en su creación (constructor) que le pase un DNI no podria utilizarlo?
Esto ya se escapa de mis conocimientos. He visto algún video de MVC donde indican que siempre que se cree un modelo los campos clave deben pasarse en el constructor, no pudiendo dejar este metodo sin valores a menos que la tabla mapeada no cuente con claves. Los get/setters se usan para aquellos campos que no son clave. Más cosas, si usas el patrón fabrica no podrias hacer inyección de dependencias en un constructor? ...es decir el constuctor (con parámetros) como tal no tiene sentido si piensas utilizar tus clases dentro de una fábrica.
El constructor puede tener los parámetros o sin parámetros que desees, eso depende del programador... La fábrica solo devuelve una instancia, si deseas pasar parámetros en el constructor aparte de pasar el tipo para obtener una instancia podrias enviar luego valores como un atributo más (en un String separados x comas) y eso enviarlo al constructor trabajando con un algoritmo split, es más que todo ya lógica de programación
Genial vídeo! Muy bien explicado! Tengro una pregunta: Se podría decir que la Fábrica es una clase en donde se usan muchos IFs para devolver una instancia especifica según el parámetro dado? ¿Esto siempre se cumple? Y si se quieren añadir más opciones serían más IFs, ¿cierto?
Entonces no es una clase; sino una estructura de datos. Y sí, la Fábrica es una estructura de datos encargada de crear clases que comparten comportamiento heredado de una interfaz
Hola Mito sé que ya pasaron 2 años de que subiste el tutorial pero ¿No crees que es más conveniente hacer el método que retorna la instancia estático ? Así la fábrica no crea una instancia por cliente para retornar la instancia solicitada ....Espero me puedas contestar Excelente tutorial
El Contenedor de Spring antes era una Fabrica de Beans verdad? y con la aparicion de la inversion de control ya no necesitamos depender de el o eso entiendo xd
Na verdade, o piliformismo não necessita que se diga explicitamente qual o tipo do objeto, como existe com a implementações de vários IFs. Aí, não existe piliformismo.
Yo hice la fabrica de otra manera para poder validar cuando metan motores de BD invalidos y asi no uso una clase poco util como ConexionVacia (que con todo respeto, es poco elegante usarla de esa forma): package com.fdxsoft.pattern; import com.fdxsoft.pattern.imp.ConexionMSSQL; import com.fdxsoft.pattern.imp.ConexionMySQL; import com.fdxsoft.pattern.imp.ConexionOracle; import com.fdxsoft.pattern.imp.ConexionPostgreSQL; public class ConexionFabrica { public IConexion getConexion(String motor) throws Exception { if(motor==null) { throw new Exception("Tiene que especificar un motor de conexion!"); } switch(motor.toUpperCase()) { case "MYSQL": return new ConexionMySQL(); case "ORACLE": return new ConexionOracle(); case "POSGRESQL": return new ConexionPostgreSQL(); case "MSSQL": return new ConexionMSSQL(); default: throw new Exception("Motor de Base de Datos Invalido!"); } } } Y mi app lo utilizaria de la siguiente manera: package com.fdxsoft.main; import com.fdxsoft.pattern.ConexionFabrica; import com.fdxsoft.pattern.IConexion; public class App { public static void main(String[] args) { //Instanciamos primero la fabrica de conexiones ConexionFabrica cf = new ConexionFabrica();
Lo único que no me convence del todo es la forma que manejas el Try - Catch, literalmente eso es un code smell por donde lo mires. No hay forma de que, de no arreglarlo, no termine mal. Si yo fuera tú tendría algo como el patrón "Decorador", cosa que encapsule la obtención de las instancias en un único método y ese método lo tendría dentro de un Try - Catch. También, para mejorar el encapsulamiento haría un pequeño refactor a la Fábrica, cosa que quede tal que así: public static Conexion getConexion(String motorBaseDatos) { if (estaVacio(motorBaseDatos)) { throw new ConexionNoEncontradaExcepcion( ); } return buscarConexion(motorBaseDatos); } private static Conexion buscarConexion(String motor) { return switch (motor.toUpperCase()) { case "MYSQL" -> new ConexionMySQL(); case "ORACLE" -> new ConexionOracle(); case "POSTGRE" -> new ConexionPostgre(); case "SQL" -> new ConexionSQLServer(); default -> throw new ConexionNoEncontradaExcepcion( ); }; } private static boolean estaVacio(String motor) { return Objects.isNull(motor); }
@@jaredM_2710 esta probado y funciona correctamente, no hay forma de que truene, y te reto a que me digas como hacerlo tronar si segun tu crees que puede terminar mal
Me gustan las explicaciones, aunque tienes demasiados "else if" innecesarios y un "if" también innecesario. Además de que no cumples del todo con el encapsulamiento del Clean Code (dado que tienes las condiciones buleanas expuestas y no ocultas como debe ser)
Te digo algo muy sencillo: De todo lo que he buscado para entender el tema, eres el único que lo ha sabido explicar bien, el resto de videos que he visto hablan pura basura y no explican bien cómo funciona... Excelente... Saludos
Hoy en un proyecto que estoy trabajando, me di cuenta que necesitaba una fábrica porque cambio a cada rato de base de datos y sería bueno pasarle un String por variable de entorno, un video muy útil! Gracias 😄
Muy bueno hermano, yo gusto la clareza de los ejemplos :)
Genial, explicado con ejemplos de códigos y gráficos. De manera fácil, sencilla y clara. Da gusto aprender así.
Mi enhorabuena y sobretodo gracias por tratar un tema tan poco tratado por otros canales pero de tanta importancia como son los Patrones de Diseño
Excelente. El mejor tutorial que he visto de esta materia.
La mejor explicación que encontr sobre el patron! Te agradezco muchisimo!
Espectacular tu explicación. Al fin entendí.
Ayer me queme la cabeza por dos horas buscando una explicación coherente.... y hoy, a mitad de tu video, ya entendia como funcionaba. Suscribo.
Edit: es curioso, pero creó q es mas fácil de explicar, en parte, porque la clase Factory del ejemplo no respeta él segundo principio SOLID. La mayoría de los ejemplos ya lo implementaban pero se volvia complejo a la vista. Una buena decisión ahí.
Buenisimo, es genial que cambies los nombres que se usan en ingles a español y contextualizar con ejemplos, eso hace que todo sea mucho mas facil de entender bro! asi que tome su buen like señor programador.
Parabéns, didática muito clara.
A desvantagem que eu vejo no padrão Fábrica, é a necessidade de alterar o Shape quando surgirem novas implementações, ele não trabalha de maneira extensiva, ou seja, a classe está aberta para modificação e fechada para extensão, algo que vai de encontro ao princípio SOLID.
Es de locos... Recién empiezo con esto de los patrones y tanto Singleton como Factory los implemente sin darme cuenta.
Tenia un problema para un juego RPG por turno que estoy tratando de terminar y se me ocurrió hacer una interfaz para las Acciones (ataque, defensa, cargar y huir) y también hice una clase con un metodo estático, que es la que ejecuta la acción, acorde a lo que el usuario elija, recibiendo como parametro un int, los cuales fije constantes para el tipo de acción, en base a eso...
Lo único, mi "factoria" la hice con switch.
Muchas gracias por el conocimiento que siempre nos compartes. Saludos desde Colombia.
Excelente explicación, yo estaba leyendo un libro llamado Head First Patters, y al complementario con tu video me quedo más claro este patrón, gracias
El ejemplo del pato es genial :P
Mito explicas excelente!! del ejemplo que nos regalas, en la clase ConexionFabrica reemplazaria los elseif por un switch para evitar el codigo espagueti, de resto todo perfecto
Recuerdo haber visto tu canal hace muchos años atrás (al menos 4 años), y en ese entonces no me pareció un buen canal. Creo que hoy debo reconocer que has mejorado muchísimo en cuanto a la generación de contenido. Muy buenos tutoriales, muy claros, gracias por el trabajo y el tiempo invertido bro!
Según un texto sobre la convención de nombres de java, que si no mal recuerdo era de la misma Oracle, cada palabra debe empezar con mayúscula y luego seguir con solo minúsculas (típico camel case). Esto es cierto incluso para aquellas palabras que son iniciales o siglas con algún significado. Por ejemplo:
sedeDeLaONU -> incorrecto
sedeDeLaOnu -> correcto
El texto también indicaba que están consientes de que la propia API estándar de java rompe dicha convención en ocasiones, pero al parecer solo se mantienen esos nombres irregulares por compatibilidad hacia atrás.
Por lo tanto, la forma correcta sería: ComexionMySql, MongoDb, IdPersona, etc...
Excelente aclaración, es un error muy común. Gracias!!!
Me parecen excelentes estos tutoriales, cada día aprendo más
Hermosa explicación!
Por fin encuentro vídeos fáciles de entender. Muchas gracias!!
Se agradece profundamente tu dedicación para estos cursos.
Me da la sensación que lo que se explica en este video según lo que he podido ver hoy es un un Simple Idiom Factory, ya que tu código sigue dependiendo de un hardcode en la fábrica por medio de EqualsIgnoreCase, lo que viola el principio SOLID de Open Close. En otros lados he visto que para evitar esto generan una clase abstracta cuyo método abstracto debe ser sobrescrito en las clases que hereden de esta en cuyo interior estan los métodos ya implementados de la Interfaz.
Muy clara la explicación , recomendado
Felicitaciones Jaime Medina !!!
Me encanto excelente explicación. Gracias
Es correcto decir que la notacion @Qualifier en spring, funciona bajo el patrón de diseño fabrica?
gracias por los vídeos. están geniales 👍👏👏👏
pero creo que en este ejemplo concreto se viola el Open-Close Principle ;-)
Verdade, fiz um comentário sobre isso.
Apesar que, em caso de uma nova implementação, somente a Fábrica seria modificada, ou seja, tem a única responsabilidade de prover implementações.
Mas realmente, não está extensível
eso mismo estaba pensando
La verdad este tutorial esta de respeto le doy un 10
está de respeto jajaj ta' buena la frase
Gracias. Lo programare.
Buenisimos sus videos men siga haciendo mas :D
puedo usar una Clase abstracta en lugar de una interfaz?
Muchas gracias Jaime! Excelente como siempre
Gracias. Muy útil
Buen video, gracias por la explicación...
se entendio todo, gracias.
Buen video, gracias por tu aporte, te la volaste con la manita arriba jajajaja
una pregunta, en el patrón Fabrica se pueden implementar otros métodos, no solo crear sino por ejemplo de búsqueda.
A efectos prácticos Factory y Strategy realmente se diferencian en algo?
yo estoy confundido, este es el mismo de factory method? que a su vez es distinto del de abstract factory?
maginifico, solo un pequeño inciso, crees que estaria bien que en vez de crear todos esos condicionales en la funcion getConexion, quitarlos y poner un array asociativo y retornarlo directamente? o no.Muchas graicas por el aporte
Mucho talento
Estuvo muy productivo!
Hola amigo, este ejemplo se refiere al Patron de diseño Factory Method en Ingles?
Genial, gracias por los aportes!
Factory más que ser usado para que solo regrese una instancia, para lo que se usa es para construir objetos con una larga cantidad de parámetro en el constructor
se me ocurre otro contexto donde puede ser útil este patron, por ejemplo para la programación de un juego, instanciar por medio de la fabrica ciertos enemigos que eventualmente cuando destruyas se borraran automaticamente
Me parece un excelente ejemplo, crear enemigos según su tipo o nombre
Excelente
Muy bien la explicacion, pero creo que hubiera sido mejor que coincida el ejemplo que usaste en codigo (conexion a bases de datos) y el del diagrama (formas geometricas)
haces clases particulares?
¿Buenas , que pasaría si las implementaciones no necesitan todos los métodos definidos en la Interfaz?
Las implementaciones deben sobrescribir los métodos de la interfaz, así no los usen. Las interfaces obligan a las clases que las implementan a que usen esos métodos. De eso se trata una interfaz, de crear una estructura que sea de uso obligatorio para quien lo implemente
UUUUUU, re excelente video.
Tengo unas dudas xd.
También se podría hacer static el método getConexion?
Muchas gracias! Me sirvió
es buenisima la explicacion pero cuando dice factoria me viene un reggaeton a la cabeza jajaja
Excelente, muchas gracias
Excelente. Superclaro
supeer!
Hola, donde podría conseguir información sobre la siguiente terminología: Caso de uso, cliente y dominio. Esto son conceptos de UML?
Si es UML, lee libros y artículos de Martin Fowler
El patrón Fábrica solo es aplicable en clases que no requieran parámetros en su constructor?. Por ejemplo si tengo un modelo Clientes y este requiere en su creación (constructor) que le pase un DNI no podria utilizarlo?
Pues para eso luego están los get y setters tras retornar la instancia
Esto ya se escapa de mis conocimientos. He visto algún video de MVC donde indican que siempre que se cree un modelo los campos clave deben pasarse en el constructor, no pudiendo dejar este metodo sin valores a menos que la tabla mapeada no cuente con claves. Los get/setters se usan para aquellos campos que no son clave. Más cosas, si usas el patrón fabrica no podrias hacer inyección de dependencias en un constructor? ...es decir el constuctor (con parámetros) como tal no tiene sentido si piensas utilizar tus clases dentro de una fábrica.
El constructor puede tener los parámetros o sin parámetros que desees, eso depende del programador... La fábrica solo devuelve una instancia, si deseas pasar parámetros en el constructor aparte de pasar el tipo para obtener una instancia podrias enviar luego valores como un atributo más (en un String separados x comas) y eso enviarlo al constructor trabajando con un algoritmo split, es más que todo ya lógica de programación
Si todo muy bonito pero le falto explicar cuando usarlo
Muchas Gracias,
Muy bueno ahora entiendo jjaa .tenes mucha pedagojia
El método getconexion podría ser estático para no tener que instanciar la fábrica?
Si deseas
Gracias amigo
Esta bien explicado :D Gracias
Genial vídeo! Muy bien explicado!
Tengro una pregunta: Se podría decir que la Fábrica es una clase en donde se usan muchos IFs para devolver una instancia especifica según el parámetro dado? ¿Esto siempre se cumple?
Y si se quieren añadir más opciones serían más IFs, ¿cierto?
Hola, espero que estés bien.
Por lo que vi en el video y entendí, sí es así como dices.
@@javiervaleriano2920 Hola, espero que tu igual 😁
Muchas gracias por responder, m ayuda a aclarar este concepto
O puedes implementar un switch en vez de varios if.
Entonces no es una clase; sino una estructura de datos. Y sí, la Fábrica es una estructura de datos encargada de crear clases que comparten comportamiento heredado de una interfaz
Hola Mito sé que ya pasaron 2 años de que subiste el tutorial pero ¿No crees que es más conveniente hacer el método que retorna la instancia estático ? Así la fábrica no crea una instancia por cliente para retornar la instancia solicitada ....Espero me puedas contestar Excelente tutorial
¿Que diferencia un Factory de una inyeccion de dependencias?. Gracias.
code.i-harness.com/es/q/882ae
El Contenedor de Spring antes era una Fabrica de Beans verdad? y con la aparicion de la inversion de control ya no necesitamos depender de el o eso entiendo xd
psss ultimamente el sonar cube dice que no esta chido meter tantos if anidados, y me recomienda cambiarlo por un switch xD
muito bem explicado.
Ejemplo de polimorfismo también. :)
Na verdade, o piliformismo não necessita que se diga explicitamente qual o tipo do objeto, como existe com a implementações de vários IFs. Aí, não existe piliformismo.
Yo hice la fabrica de otra manera para poder validar cuando metan motores de BD invalidos y asi no uso una clase poco util como ConexionVacia (que con todo respeto, es poco elegante usarla de esa forma):
package com.fdxsoft.pattern;
import com.fdxsoft.pattern.imp.ConexionMSSQL;
import com.fdxsoft.pattern.imp.ConexionMySQL;
import com.fdxsoft.pattern.imp.ConexionOracle;
import com.fdxsoft.pattern.imp.ConexionPostgreSQL;
public class ConexionFabrica {
public IConexion getConexion(String motor) throws Exception {
if(motor==null) {
throw new Exception("Tiene que especificar un motor de conexion!");
}
switch(motor.toUpperCase()) {
case "MYSQL":
return new ConexionMySQL();
case "ORACLE":
return new ConexionOracle();
case "POSGRESQL":
return new ConexionPostgreSQL();
case "MSSQL":
return new ConexionMSSQL();
default:
throw new Exception("Motor de Base de Datos Invalido!");
}
}
}
Y mi app lo utilizaria de la siguiente manera:
package com.fdxsoft.main;
import com.fdxsoft.pattern.ConexionFabrica;
import com.fdxsoft.pattern.IConexion;
public class App {
public static void main(String[] args) {
//Instanciamos primero la fabrica de conexiones
ConexionFabrica cf = new ConexionFabrica();
try {
//Ahora le vamos solicitando cada uno de los tipos de conexion disponibles
IConexion cx1 = cf.getConexion("MSSQL");
cx1.conectar();
cx1.desconectar();
IConexion cx2 = cf.getConexion("MYSQL");
cx2.conectar();
cx2.desconectar();
IConexion cx3 = cf.getConexion("posgresql");
cx3.conectar();
cx3.desconectar();
IConexion cx4 = cf.getConexion("oRACLE");
cx4.conectar();
cx4.desconectar();
/*
IConexion cx5 = cf.getConexion(null);
cx5.conectar();
cx5.desconectar();
*/
IConexion cx6 = cf.getConexion("bd_no_soportada");
cx6.conectar();
cx6.desconectar();
}catch(Exception e) {
System.out.println("ERROR: " + e.getMessage());
}
}
}
Lo único que no me convence del todo es la forma que manejas el Try - Catch, literalmente eso es un code smell por donde lo mires. No hay forma de que, de no arreglarlo, no termine mal.
Si yo fuera tú tendría algo como el patrón "Decorador", cosa que encapsule la obtención de las instancias en un único método y ese método lo tendría dentro de un Try - Catch.
También, para mejorar el encapsulamiento haría un pequeño refactor a la Fábrica, cosa que quede tal que así:
public static Conexion getConexion(String motorBaseDatos) {
if (estaVacio(motorBaseDatos)) {
throw new ConexionNoEncontradaExcepcion( );
}
return buscarConexion(motorBaseDatos);
}
private static Conexion buscarConexion(String motor) {
return switch (motor.toUpperCase()) {
case "MYSQL" -> new ConexionMySQL();
case "ORACLE" -> new ConexionOracle();
case "POSTGRE" -> new ConexionPostgre();
case "SQL" -> new ConexionSQLServer();
default -> throw new ConexionNoEncontradaExcepcion( );
};
}
private static boolean estaVacio(String motor) {
return Objects.isNull(motor);
}
@@jaredM_2710 esta probado y funciona correctamente, no hay forma de que truene, y te reto a que me digas como hacerlo tronar si segun tu crees que puede terminar mal
+10
Mitocode alguna experiencia real en el que hayas usado ese patron
Hace unos 4 años vi que justamente cambiaban al motor de base de datos dependiendo el producto que la empresa daba soporte
Me gustan las explicaciones, aunque tienes demasiados "else if" innecesarios y un "if" también innecesario.
Además de que no cumples del todo con el encapsulamiento del Clean Code (dado que tienes las condiciones buleanas expuestas y no ocultas como debe ser)
no le entendi ni madres :(
Excelente, muchas gracias