El Patrón de Diseño Strategy define una familia de algoritmos, encapsula cada uno y los hace intercambiables a través del uso de polimorfismo, en este breve artículo te proporcionaremos una introducción a este patrón de diseño y cómo usarlo.
En Laravel tenemos una clase para enviar emails que utiliza diferentes mecanismos o «transportes»; puedes enviar un correo vía SMTP, a través de Mailgun o incluso guardar correos en un archivo de log.
Pero si revisas el código de la clase Mailer no encontrarás esto:
<?php class Mailer { public function send($email) { switch ($this->transport) { case 'smtp': return $this->sendUsingSmtp($email); case 'mailgun': return $this->sendWithMailgun($email); case 'log': return $this->logToAFile($email); } } }
Porque elegir la manera de enviar correos usando condicionales haría el código difícil de cambiar, además cada método de envío requiere de información o clases extra (por ejemplo, un token o la clase Logger
), lo cual terminaría por complicar la clase Mailer
con muchos métodos e información no relacionada entre sí.
Por el contrario, lo que hace Laravel o, mejor dicho, SwiftMailer, es definir una serie de transportes cada uno como una clase diferente y todos con la misma interfaz Transport
. Al instanciar un objeto de la clase Mailer
simplemente debes pasar el transporte que quieras usar, por ejemplo en local quizás quieras guardar en un log:
<?php $mailer = new Mailer(new LogTransport('storage/log.txt'));
Pero en producción enviar vía SMTP:
<?php $mailer = new Mailer(new SmtpTransport($credenciales));
A partir de aquí el transporte usado resulta transparente:
<?php $mailer->send($email);
Aunque, por supuesto, $mailer
delegará el envío al transporte usado:
class Mailer { public function send($email) { return $this->transport->send($email); } }
Nota que los condicionales han desaparecido, crear un nuevo «mecanismo de transporte» para enviar correos es tan sencillo como crear una nueva clase que extienda o implemente Transport
y pasarla a la clase Mailer
. Incluso podrías usar los transportes en otras clases sin problema:
<?php new CampaignMailer(new MailChimpTransport($credentials)); new BulkMailer(new MailgunTransport);
Lo cual sería muy difícil o engorroso de lograr utilizando sólo condicionales o herencia, puesto que con esta última técnica terminaríamos con muchas clases y código duplicado.
Este artículo es un pequeño ejemplo y resumen de lo aprendido sobre el Patrón Strategy en nuestro Curso de Patrones de Diseño con PHP.
Material Relacionado
- Patrón Strategy: Creación del proyecto de ejemplo
- Interfaces y Polimorfismo
- Curso de programación orientada a objetos con PHP
- Curso de Patrones de Diseño con PHP
- Curso de Refactorización con PHP
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.