toniGitH /
Patron-Prototype
Explicación del patrón Prototype y ejemplo de uso en PHP
Loading repository data…
toniGitH / repository
Explicación del patrón Builder y ejemplo de uso en PHP
Repositorio creado para explicar el patrón Builder y su implementación mediante un ejemplo práctico en PHP (Tienda de ordenadores).
Builder es un patrón de diseño creacional que externaliza la lógica de construcción de un objeto complejo fuera de su propia clase, sustituyendo la instanciación directa convencional por un proceso de creación por pasos o fases. Bajo este enfoque, la clase del producto deja de ser responsable de su propia fabricación detallada, delegando dicha tarea a una entidad externa dedicada.
Para ello, define una interfaz o clase abstracta Builder que declara los requisitos necesarios para construir un producto, delegando en las clases que la implementan Builders Concretos la responsabilidad de ejecutar cada fase y producir el resultado final Producto concreto.
Dicho resultado final puede ser tanto productos complejos de la misma naturaleza (de la misma clase), como productos de naturalezas totalmente distintas (clases diferentes). El único requisito es que todos ellos compartan un mismo proceso de fabricación, es decir, que todos ellos requieran de los mismos pasos o fases para ser construidos.
Este patrón permite crear objetos complejos paso a paso de forma organizada, evitando constructores con múltiples parámetros, utilizando una misma secuencia de órdenes, la cual puede estar orquestada por una clase dedicada opcional (Director) para independizar al Cliente de los detalles específicos de fabricación.
Dado que este patrón es de tipo creacional, lo primero a tener en cuenta para comprenderlo bien es que se enfoca en la creación de objetos (producto concreto), al igual que otros patrones como el Singleton, el Factory Method o el Abstract Factory.
En el caso del patrón Builder, otro detalle fundamental que es los objetos en los que se enfoca son objetos complejos, es decir, objetos que requieren de múltiples pasos para ser creados. Suelen tener muchas propiedades que pueden tomar diversos valores, así como un proceso de fabricación que implica varios métodos o pasos.
Para objetos simples, lo normal es que ese objeto (producto concreto) se cree directamente desde el constructor de su propia clase ProductoConcreto, pasándole todos los parámetros necesarios para su creación. Sin embargo, cuando un objeto es muy complejo, con muchas propiedades y un proceso de fabricación largo y complicado, el constructor puede volverse muy grande y difícil de manejar.
En esos casos puede ser útil la aplicación del patrón Builder, para extraer toda esa lógica de construcción fuera de la clase del objeto ProductoConcreto y colocarla en una clase dedicada a ello, en un BuilderConcreto.
La creación del objeto como tal, sigue en manos del constructor de la clase ProductoConcreto, pero el patrón Builder nos permite recuperar ese objeto y aplicarle, externamente, todos los pasos necesarios para convertirlo en el objeto complejo final que necesitamos.
El objeto (producto concreto) se sigue basándose en una instrución de tipo new ProductoConcreto(), pero en lugar de que ésta produzca el producto final, generará una especie de "producto concreto en bruto", al que posteriormente se le aplicarán todos los pasos necesarios para convertirlo en el "producto concreto final" que necesitamos.
Opcionalmente, la orquestación de todos esos pasos o fases del proceso de fabricación aplicadas al producto en bruto, puede estar a cargo de una *clase dedicada opcional Director para independizar al Cliente de los detalles específicos de fabricación.
En este caso, suele ser habitual que el Director cuente con una serie de métodos que representan diferentes recetas o procesos de fabricación, cada uno de los cuales está compuesto por una secuencia específica de pasos que se aplican al producto en bruto para obtener un producto final diferente.
1️⃣ Interface Builder
Es el contrato genérico que define los pasos de fabricación y que contiene todos los métodos que definen los pasos de fabricación y que deben ser implementados por los Builders concretos.
Entre los métodos que incluye, típicamente suele contener un método reset(), que sirve para:
2️⃣ BuilderConcreto
Son clases que implementan la interfaz Builder y que definen los pasos de fabricación de los objetos del tipo a que corresponde ese builder concreto.
Es muy importante advertir dos cosas importantes:
3️⃣ Producto concreto
Son clases que representan los objetos concretos a construir.
La aplicación de este patrón permite que se puedan crear productos de naturalezas totalmente distintas (clases diferentes), siempre y cuando dichos objetos que pertenecen a esas clases diferentes compartan un proceso de creación común, definido por los métodos declarados en la interfaz Builder.
Por tanto, las diferentes clases que representan a esos productos concretos, no tienen por qué tener nada en común entre sí (pueden tener propiedades totalmente diferentes, incluso ninguna en común) excepto ese proceso de creación común.
Aclaración importante sobre la idea de lo que es un proceso de creación común o compartido
La interfaz Builder declara una serie de métodos o pasos de fabricación, y TODOS esos pasos o métodos DEBEN ser útiles o relevantes para la creación de TODOS los objetos concretos que se quieren crear con este patrón, pero eso no significa que para construir todos y cada uno de dichos objetos siempre haya que llamarlos a todos.
Cada método debe ser susceptible de ser utilizado para cada objeto concreto, pero según cada caso, tal vez un objeto concreto no necesite llamar a alguno de ellos.
Por ejemplo, en el caso de la tienda de ordenadores, no todos los ordenadores necesitan tarjeta gráfica (gpu), por lo que no todos los ordenadores necesitarán llamar al método
gpu(), pero ese método, aunque en un determinado caso no se use, es relevante en general (no es un método inútil que NUNCA es necesario).Y esto se debe cumplir, sea cual sea la naturaleza de los objetos a construir. Si algún tipo de objeto no necesita NUNCA alguno de los métodos declarados en la interfaz Builder, pero otros objetos de otra naturaleza sí, entonces ese tipo de objeto no debería ser creado con este patrón.
4️⃣ Director
Esta es una clase opcional que define el orden de ejecución de los pasos para crear modelos predefinidos o predeterminados.
5️⃣ Cliente
Es la entidad que orquesta el uso del patrón para obtener los productos.
Imagina este patrón como la fabiración de un ordenador. La clase del objeto podría ser una clase Computer, que contendría todos los atributos o propiedades del ordenador, pero con este patrón Builder, esta clase sólo sería capaz de crear una especie de ordenador en bruto, mientras que todos los pasos para montarlo serían extraidos a una clase dedicada a ello ComputerBuilder, incluido un método para retornar el objeto final.
De esta manera, podríamos tener una clase Computer y una clase ComputerBuilder, con las que podríamos crear fácilmente diferentes ordenadores, es decir, diferentes objetos complejos de la misma naturaleza de la misma clase, Computer, siempre que todos ellos se creen mediante los mismos pasos, aunque haya una infinidad de variaciones de procesadores, RAM, SSD, etc.
Pero, además de esto, el patrón Builder nos permite crear productos de naturalezas totalmente distintas (clases diferentes), siempre y cuando dichos objetos que pertenecen a esas clases diferentes, compartan una misma secuencia de órdenes.
Por ejemplo, imagina que, además de fabricar ese ordenador, queramos crear un manual de cómo usar ese ordenador, destinado al usuario final o al departamento de soporte técnico, y/o una factura que refleje el coste de fabricación de dicho ordenador, destinada al departamento de contabilidad. Evidentemente, un ordenador, un manual de instrucciones o una factura, son objetos de naturaleza completamente diferentes, pero si comparten la misma secuencia de creación, el patrón Builder nos permitirá crearlos todos a partir de la misma secuencia de órdenes.
Así, tendríamos diferentes clases que representarían objetos de diferentes naturalezas, como Computer, UserManual e Invoice, cuya secuencia de creación sería la misma, la interface Builder, aunque con propiedades diferentes y con una implementación diferente de esos pasos comunes de fabricación, concretada cada una de ellas en cada uno de los builders concretos ComputerBuilder, UserManualBuilder y InvoiceBuilder.
Los escenarios más típicos en los que nos puede interesar aplicar el patrón Builder son:
📌 Constructores "telescópicos": cuando empiezas a tener constructores con demasiados parámetros opcionales que te obligan a pasar muchos null o crear múltiples versiones del constructor.
📌 Procesos de creación por fases: cuando el objeto no se puede (o no se debe) crear en un solo instante, sino que requiere obtener datos en distintos momentos (ej: un formulario web de varios pasos).
📌 **Necesidad de
Selected from shared topics, language and repository description—not editorial ratings.
toniGitH /
Explicación del patrón Prototype y ejemplo de uso en PHP
toniGitH /
Explicación del patrón Singleton y ejemplo de uso en PHP
toniGitH /
Explicación del patrón Adapter y ejemplo de uso en PHP
toniGitH /
Explicación del patrón Facade y ejemplo de uso en PHP
toniGitH /
Explicación del patrón Decorator y ejemplo de uso en PHP
toniGitH /
Explicación del patrón Abstract Factory y ejemplo de uso en PHP