¿Qué es el patrón Factory y por qué es tan utilizado en desarrollo?
El patrón de diseño Factory (fábrica) es una herramienta fundamental en la programación que nos permite crear instancias de clases de manera eficiente. Este patrón se emplea frecuentemente para gestionar mensajes de error, mensajes informativos u otros diálogos que puedan ayudar a los usuarios. El Factory es responsable de generar la instancia adecuada dependiendo del tipo de mensaje solicitado, lo que hace que el desarrollo sea más ordenado y el código más fácil de mantener.
¿Cuáles son los beneficios del patrón Factory?
Este patrón ofrece múltiples beneficios, entre ellos:
Abstracción de la implementación: Al solicitar un diálogo, no necesitas conocer su implementación interna. Solo debes indicar el tipo de mensaje que deseas y el Factory te proporcionará la instancia correspondiente.
Flexible y expandible: Puedes agregar o modificar tipos de mensaje sin alterar el código que los llama. La factoría se encarga de gestionar estos cambios de manera interna.
Transparencia: Al llamar al Factory, solo debes proporcionar el tipo de mensaje, y cualquier modificación o agregado en los tipos es transparente para el resto del sistema.
¿Cómo se implementa un Factory en el código?
Creación de la clase Factory
Para ilustrar cómo se implementa un Factory, imaginemos que queremos manejar mensajes de éxito y error en un proyecto. Comenzaremos creando una clase MessageFactory en el nivel de datos del proyecto.
class MessageFactory {companionobject{val TYPE_ERROR ="error"val TYPE_SUCCESS ="success"}fungetDialog(type: String): AlertDialog.Builder{returnwhen(type){ TYPE_ERROR ->{ AlertDialog.Builder(context).setMessage("Error al cargar el contenido")} TYPE_SUCCESS ->{ AlertDialog.Builder(context).setMessage("Contenido cargado exitosamente")}else->{ AlertDialog.Builder(context).setMessage("Tipo no reconocido")}}}}
En este ejemplo, vemos cómo MessageFactory gestiona diferentes tipos de mensajes, retornando instancias de AlertDialog.Builder según el tipo recibido.
Integración del Factory en una vista o fragmento
Para utilizar este Factory en una vista, como un fragmento, hacemos lo siguiente:
Aquí, el fragmento HomeFragment solicita al MessageFactory un diálogo de error, que luego es mostrado al usuario.
¿Por qué cada clase debe tener una única responsabilidad?
El principio de responsabilidad única es crucial en el desarrollo de software, ya que cada clase debe manejar una única función o tarea. En este contexto, el uso del patrón Factory garantiza que cada componente del sistema tenga claramente definida su función sin solapar responsabilidades. Esto no solo mejora la legibilidad y el mantenimiento del código, sino que también asegura un desarrollo más eficiente y organizado, permitiendo a los programadores agregar nuevas funcionalidades con facilidad.
Consejos prácticos
Documenta los tipos disponibles en tu Factory: Asegúrate de que todos los desarrolladores comprendan los tipos de mensajes que puede gestionar y cómo utilizarlos.
Mantén el código limpio y organizado: Use convenciones de nomenclatura consistentes como CamelCase y asegúrate de que las funciones se mantengan concisas y en un solo propósito.
Prueba a fondo los cambios en el Factory: Antes de integrar nuevos tipos de mensajes, verifica que tu implementación sea robusta y que no rompa ninguna funcionalidad existente.
Este sólido enfoque haciendo uso del patrón Factory no solo optimiza el flujo de trabajo de desarrollo, sino que también fomenta la creación de aplicaciones más escalables y adaptables a nuevas necesidades. Continúa explorando y aplicando estos principios para convertirte en un desarrollador aún más competente y versátil.
la función que hiciste de getDialog() te puedes evitar los
{}
kotlin no es necesario tenerlos de hecho la función podría quedar algo como :
fun getDialog(context:Contex,type:String)=when(type){TYPE_ERROR->AlertDialog.Builder(context).setMessage("mensaje error")TYPE_SUCCESS->AlertDialog.Builder(context).setMessage("mensaje correcto")else->AlertDialog.Builder(context).setMessage("no reconozco el tipo")}
Es posible crear los tipos en un enum?
Sí, de hecho es una mejor practica que usar strings
Es un patrón que es muy usado a nivel de desarrollado mobile porque muchas veces tenemos que mostrar mensajes de error, información o mensajes que ayudarán al usuario.
Para este caso usar Enum sería mucho mejor que usar Strings
x2
con factory no se conoce detalle de la implementacion, solo pedimos un tipo y nos lo fabrica y sirve
Factory nos ayuda a tener instancias de un objeto dado el tipo.
Entiendo que si en vez de "class MessageFactory" ocupamos "object MessageFactory" seria como tener el Factory dentro de un Singleton, y se podría ocupar en todo el programa sin necesitad de crear una instancia cada que se ocupe o en cada clase ¿No hay inconveniente en esto?
Exacto, pero recuerda que un Singleton también es un anti patrón, por que no es testeable y queda vivo en toda la instancia de la aplicación. Es mejor utilizar la instancia cuando sea necesaria y permitir que luego sea borrada de memoria, con ello tienes mayor performance
Las clase se manejan en ingles y camelcase
También, para hacer el código más legible podríamos implementar la función lambda con los valores explícitos, reemplazando el it.
Hola, creo que en el método getDialog(), es oportuno utilizar el else, del when, y no utilizar tantas veces el return
fun getDialog(context:Context,type:String):AlertDialog.Builder{vartypeToReturn:AlertDialog.Builderwhen(type){TYPE_ERROR->{ typeToReturn =AlertDialog.Builder(context).setMessage("Hay un error en la comunicación")}TYPE_SUCCESS->{ typeToReturn =AlertDialog.Builder(context).setMessage("Exitoso")}else->{ typeToReturn =AlertDialog.Builder(context).setMessage("No se encontró el tipo")}}return typeToReturn
}
Para el contexto es mejor usar requireContext()
**Factory **nos ayuda a tener instancias de un objeto dado el tipo
Tenemos las ventaja de que la responsabilidad de creación de las clases se delega al Factory y los usamos a base de abstracciones (interfaces).