Вы находитесь на странице: 1из 35

Patrones de diseo con PHP

Qu son los patrones de diseo?

Los patrones de diseo son soluciones para problemas tpicos y recurrentes: acceso a datos,
creacin de objetos, operaciones entre sistemas etc. En lugar de reinventar la rueda,
utilizamos algn patrn, que son soluciones probadas y documentadas. Control de cohesin
y acoplamiento o reutilizacin de cdigo son algunos de los beneficios que podemos
conseguir al utilizar patrones.

Un patrn es una regla con tres partes que expresa la relacin entre un determinado
contexto, un problema y una solucin.

Usar patrones facilita la gestin del cdigo y permite a otros desarrolladores entender
fcilmente cada una de las partes que forman la aplicacin.

Patrones de diseo hay muchos y siguen apareciendo patrones nuevos cada poco tiempo. Es
imposible conocerlos a todos. Lo ms til es tener un catlogo al que podamos consultar
buscando patrones que nos ayuden a solucionar problemas de diseo concretos.
Algunos ejemplos de catlogos:
http://www.oodesign.com/
http://en.wikipedia.org/wiki/Software_design_pattern
http://c2.com/cgi/wiki?GangOfFour

Patrones creacionales

Los patrones creacionales soportan la tarea ms comn que tiene la programacin


orientada a objetos: La creacin de las instancias de objetos. Su intencin consiste en
garantizar que una clase slo tenga una instancia y proporcionar un punto de acceso global
a ella.

1
Patrn creacional Singleton

El patrn Singleton se implementa mediante una clase con un constructor privado. Existir
un mtodo que crear UNA instancia del objeto llamando al constructor slo si todava no
existe ninguna.

Se usan para proporcionar un punto de acceso global para un servicio.


Permiten limitar la creacin de los objetos.
Promueven el acoplamiento fuerte entre clases.
Mantienen el estado hasta la finalizacin del programa.

Ejemplo de uso:
Se necesita pasar una instancia especfica de una clase a otra, entonces se usa el patrn de
instancia nica para evitar tener que pasar la instancia va el constructor o un argumento.
Creamos una clase Session, que simula el array global $_SESSION. A esta clase slo se
necesita instanciarla una vez.

Clase->

<?php
class Session
{
private static $instance;

public static function getInstance()


{
if( is_null(self::$instance) ) {
self::$instance = new self();
}
return self::$instance;
}

private function __construct() { }

private function __clone() { }

// cualquier otro mtodo(s) de sesin que usemos


...
...
...
}

2
Llamado->
<?php
// obtener una instancia de sesin
$session = Session::getInstance();
?>

Patrn creacional - Factory

Es una clase que acta como una fbrica de instancias de objetos. El principal objetivo de
este patrn es encapsular el procedimiento creacional que diferentes clases pueden tener,
en una sola funcin. Al proporcionar el contexto adecuado al mtodo de fbrica, ste ser
capaz de devolver el objeto correcto.

Ejemplo de uso:

Situacin->se tiene mltiples variantes de una sola entidad.


Se tiene una clase button, esta clase tiene diferentes variaciones, como ImageButton,
inputButton y FlashButton. Dependiendo del lugar, es posible que se deba crear diferentes
botones -aqu es donde podemos utilizar una fbrica para crear los botones.

Clase->

<?php
abstract class Button {
protected $_html;

public function getHtml()


{
return $this->_html;
}
}

class ImageButton extends Button {


protected $_html = "..."; //Este es el HTML para el botn basado en una imagen
}

class InputButton extends Button {


protected $_html = "..."; //Este es el HTML para el botn normal (<input
type="button"... />);
}

3
class FlashButton extends Button {
protected $_html = "..."; //Esti debe ser cualquier HTML que quieras usar para el
botn flash

//Factory
class ButtonFactory
{
public static function createButton($type)
{
$baseClass = 'Button';
$targetClass = ucfirst($type).$baseClass;

if (class_exists($targetClass) &&is_subclass_of($targetClass, $baseClass)) {


return new $targetClass;
} else {
throw new Exception("El tipo de botn '$type' no existe.");
}
}
}
?>

Llamado->
<?php
$buttons = array('image','input','flash');
foreach($buttons as $b) {
echo ButtonFactory::createButton($b)->getHtml()
}
?>

Patron creacional - Builder

Permite a un objeto cliente construir un objeto complejo especificando solamente su tipo y


contenido.
Este patrn abstrae el proceso de creacin de un objeto complejo, centralizando dicho
proceso en un nico punto, asi el proceso de construccin puede crear representaciones
diferentes.

Clases que participan en la estructura del patrn:

Builder: Define una interfaz abstracta para crear productos.


ConcreteBuilder: Implementacin de la interfaz Builder. Construye y rene las partes
necesarias para construir los productos.

4
Director: Construye un objeto usando la interfaz Builder.
Producto: El objeto bajo construccin.
Mtodos Propios.

Ejemplo de uso:

Clases->
<?php

abstract class AbstractPageBuilder {


abstract function getPage();
}

abstract class AbstractPageDirector {


abstract function __construct(AbstractPageBuilder $builder_in);
abstract function buildPage();
abstract function getPage();
}

class HTMLPage {
private $page = NULL;
private $page_title = NULL;
private $page_heading = NULL;
private $page_text = NULL;
function __construct() {
}
function showPage() {
return $this->page;
}
function setTitle($title_in) {
$this->page_title = $title_in;
}
function setHeading($heading_in) {
$this->page_heading = $heading_in;
}
function setText($text_in) {
$this->page_text .= $text_in;
}
function formatPage() {
$this->page = '<html>';
$this->page .= '<head><title>'.$this->page_title.'</title></head>';
$this->page .= '<body>';
$this->page .= '<h1>'.$this->page_heading.'</h1>';
$this->page .= $this->page_text;
$this->page .= '</body>';

5
$this->page .= '</html>';
}
}

class HTMLPageBuilder extends AbstractPageBuilder {


private $page = NULL;
function __construct() {
$this->page = new HTMLPage();
}
function setTitle($title_in) {
$this->page->setTitle($title_in);
}
function setHeading($heading_in) {
$this->page->setHeading($heading_in);
}
function setText($text_in) {
$this->page->setText($text_in);
}
function formatPage() {
$this->page->formatPage();
}
function getPage() {
return $this->page;
}
}

class HTMLPageDirector extends AbstractPageDirector {


private $builder = NULL;
public function __construct(AbstractPageBuilder $builder_in) {
$this->builder = $builder_in;
}
public function buildPage() {
$this->builder->setTitle('Testing the HTMLPage');
$this->builder->setHeading('Testing the HTMLPage');
$this->builder->setText('Testing, testing, testing!');
$this->builder->setText('Testing, testing, testing, or!');
$this->builder->setText('Testing, testing, testing, more!');
$this->builder->formatPage();
}
public function getPage() {
return $this->builder->getPage();
}
}
?>

Llamado->

6
<?

writeln('BEGIN TESTING BUILDER PATTERN');


writeln('');

$pageBuilder = new HTMLPageBuilder();


$pageDirector = new HTMLPageDirector($pageBuilder);
$pageDirector->buildPage();
$page = $pageDirector->GetPage();
writeln($page->showPage());
writeln('');

writeln('END TESTING BUILDER PATTERN');

function writeln($line_in) {
echo $line_in."<br/>";
}

?>

Con este ejemplo creamos una pgina html.

7
Patrones estructurales.

Los patrones estructurales estn relacionados con cmo las clases y los objetos se combinan
para dar lugar a estructuras ms complejas.

Patrn estructural - Adapter (v1):

Sirve para hacer que dos interfaces diferentes, puedan comunicarse, aadiendo un
adaptador intermedio, que se encarga de realizar la conversin de una interface a otra.
Este patrn se utiliza generalmente cundo ya existe una interface, pero no podemos (o no
queremos) usarla. Por ejemplo cuando tenemos que utilizar libreras externas

Ejemplo de uso:

Clase->

<?php
//Subscripcion
class FeedburnerEmail implements EmailSubscribe
{
public function subscribe($email) { }
public function unsubscribe($email) { }

public function sendUpdates() {


// Get Available Subscribers
// Get Website Updates
// Send Emails
}
}
//nueva versin incompatible con la anterior Subscripcion
class FeedburnerEmailVersion2
{
public function subscribe($email) { }
public function unsubscribe($email) { }

public function getSubscribers() {


// Return Subscribers

8
}

public function sendEmails($subscribers) {


// Get Website Updates
// Send Emails
echo "emails sent today";
}
}
//Adaptador
class FeedburnerAdapter implements EmailSubscribe
{
public function subscribe($email) { }
public function unsubscribe($email) { }

public function sendUpdates() {


$feedburner = new FeedburnerEmailVersion2();
$subscribers = $feedburner->getSubscribers();
$feedburner->sendEmails($subscribers);
}
}
?>

Llamado->
<?
$feedburner_email = new FeedburnerAdapter();
$feedburner_email->sendUpdates();
?>

Patrn estructural - Adapter (v2):

El patrn adaptador nos permite reutilizar una clase con una interfaz diferente, lo que
permite ser utilizada por un sistema que utiliza diferentes mtodos de llamada.
Esto tambin nos permite cambiar algunos campos que estn siendo recibidos de la clase
cliente, convirtindolos en algo compatible con las funciones adaptadas.

Otro trmino para hacer referencia a una clase adapter es wrapper, porque nos permite
envolver (wrapp) acciones en una clase y reusar estas acciones en las situaciones
adecuadas.

Ejemplo de uso:

9
Cuando se crea una clase dominio para las clases de tabla. En lugar de llamar a las diferentes
clases de tabla y llamar a sus funciones una por una, podemos encapsular todos estos
mtodos en un mtodo que utilice una clase adapter. Esto no slo nos permitir reutilizar
cualquier accin que se desee, sino tambin evitar que tengamos que reescribir el cdigo si
necesitamos usar la misma accin en un sitio distinto o en un proyecto distinto.

Sin adapter:
<?php
$user = new User();
$user->CreateOrUpdate( //inputs );

$profile = new Profile();


$profile->CreateOrUpdate( //inputs );
?>

Con adapter:

Clase->
<?php
class Account()
{
public function NewAccount( //inputs )
{
$user = new User();
$user->CreateOrUpdate( //subset of inputs );

$profile = new Profile();


$profile->CreateOrUpdate( //subset of inputs );
}
}
?>

Su uso->
<?php
$account_domain = new Account();
$account_domain->NewAccount( //inputs );
?>

10
Patrn estructural - Decorator:

Permite aadir comportamientos nuevos, o adicionales, a un objeto en tiempo de ejecucin.


Su objetivo es hacerlo de tal manera que las funciones extendidas se puedan aplicar a un
caso concreto y, al mismo tiempo, mantener la posibilidad de crear una instancia original
que no tienen las nuevas funciones. Tambin permite combinar mltiples decoradores a una
instancia, por lo que no hay que trabajar con un decorador para cada instancia.
Este patrn es una alternativa a la subclase, la cual crea una clase que hereda funcionalidad
de una clase padre. A diferencia de la subclase, que aade el comportamiento en tiempo de
compilacin, este patrn nos permite agregar un nuevo comportamiento en tiempo de
ejecucin, si la situacin as lo requiere.
Para implementar el patrn Decorator, debemos seguir los siguientes pasos:
1. Crear una subclase de la clase original Component en una clase Decorator
2. En la clase Decorator, debemos aadir un Puntero a Component como un campo
3. Pasar un Component al constructor de Decorator para inicializar el puntero
Component
4. En la clase Decorator, redirigir todos los mtodos Component al puntero
Component, y
5. En la clase Decorator, sobreescribir cualquier mtodo Component cuyo
comportamiento deba ser modificado

Ejemplo de uso:
Tenemos un elemento enlace HTML, un enlace para cerrar sesin que se requiere realice
cosas diferentes basados en la pgina en la que aparece. Aca aparece el patrn decorador.
Primero, definimos las diferentes decoraciones que necesitamos:
Si estamos en la portada como usuarios loggeados, tener el enlace dentro de
etiquetas <H2>.
Si estamos en una pgina distinta como usuarios loggeados, tener un enlace con
subrayado.
Si estamos loggeados, tener un enlace dentro de etiquetas <strong>.

Clases->

<?php
class HtmlLinks {
//algunos mtodos disponibles en todos los enlaces html
}

class LogoutLink extends HtmlLinks {


protected $_html;

11
public function __construct() {
$this->_html = "<a href="logout.php">Logout</a>";
}

public function setHtml($html)


{
$this->_html = $html;
}

public function render()


{
echo $this->_html;
}
}

class LogoutLinkH2Decorator extends HtmlLinks {


protected $_logout_link;

public function __construct( $logout_link )


{
$this->_logout_link = $logout_link;
$this->setHtml("<h2>" . $this->_html . "</h2>");
}

public function __call( $name, $args )


{
$this->_logout_link->$name($args[0]);
}
}

class LogoutLinkUnderlineDecorator extends HtmlLinks {


protected $_logout_link;

public function __construct( $logout_link )


{
$this->_logout_link = $logout_link;
$this->setHtml("<u>" . $this->_html . "</u>");
}

public function __call( $name, $args )


{
$this->_logout_link->$name($args[0]);
}
}

12
class LogoutLinkStrongDecorator extends HtmlLinks {
protected $_logout_link;

public function __construct( $logout_link )


{
$this->_logout_link = $logout_link;
$this->setHtml("<strong>" . $this->_html . "</strong>");
}

public function __call( $name, $args )


{
$this->_logout_link->$name($args[0]);
}
}
?>

Lamado->

<?php
$logout_link = new LogoutLink();

if( $is_logged_in ) {
$logout_link = new LogoutLinkStrongDecorator($logout_link);
}

if( $in_home_page ) {
$logout_link = new LogoutLinkH2Decorator($logout_link);
} else {
$logout_link = newLogoutLinkUnderlineDecorator($logout_link);
}
$logout_link->render();
?>

Patrn estructural - Facade:

El objetivo de ste patrn es el de simplificar el sistema y reducir su complejidad a travs de


la divisin en subsistemas, proporcionando una interfaz (de nivel ms alto) de acceso a
stos. El objetivo es reducir la comunicacin y dependencias entre subsistemas y, de sta
manera, conseguir un sistema ms sencillo.

13
Le da solucin al uso de varias interfaces de subsistemas mediante un nico punto de
acceso.

Se aplica cuando:
Nuestro sistema cliente tiene que acceder a parte de la funcionalidad de un sistema
complejo.
Hay tareas o configuraciones muy frecuentes y es conveniente simplificar el cdigo
de uso.
Necesitamos hacer que una librera sea ms legible.
Nuestros sistemas clientes tienen que acceder a varias APIs y queremos simplificar
dicho acceso.

Partes involucradas:
Cliente: Representa al sistema que quiere hacer uso de la clase compleja o el
conjunto de susbsistemas mediante la fachada.
Facade: Clase fachada que trata de ofrecer la funcionalidad que demanda el cliente
mediante una interfaz sencilla donde, internamente, utiliza las clases complejas.

ComplicatedClass: Conjunto de clases que se necesitan utilizar y a las que se


pretende dar un punto de acceso sencillo mediante la fachada.

Ejemplo de uso:

<?php

namespace Curso\Patrones\Facade;

class ExpedienteRepository {
private $exp = [
'1' => 'Expediente 1',
'2' => 'Expediente 2',
'3' => 'Expediente 3',
'4' => 'Expediente 4',
'5' => 'Expediente 5',
'6' => 'Expediente 6',
'7' => 'Expediente 7',

14
];

public function findById($id){


if(($i=array_key_exists($id, $this->exp))!==false) {
return $this->exp[$id];
} else {
return "";
}
}
}

namespace Curso\Patrones\Facade;

class AbogadoRepository {
private $abogados = [
'Maria', 'Pedro', 'Juliana', 'Juan', 'Alejandro',
];

public function findByNombre($nombre){


if(($i=array_search($nombre, $this->abogados))!==false) {
return $this->abogados[$i];
} else {
return "";
}
}
}

namespace Curso\Patrones\Facade;

class Facade {
private $abogadoRepository = null;
private $expedienteRepository = null;

public function __construct()

15
{
$this->abogadoRepository = new AbogadoRepository();
$this->expedienteRepository = new ExpedienteRepository();

public function buscarAbogado($nombre){


return $this->abogadoRepository->findByNombre($nombre);
}

public function buscarExpediente($id){


return $this->expedienteRepository->findById($id);
}
}

Llamada->

use \Curso\Patrones\Facade\Facade;

$facade = new Facade();

echo "Buscando a Maria " . $facade->buscarAbogado('Maria') ."\n";


echo "Buscando a Julian " . $facade->buscarAbogado('Julian')."\n";

echo $facade->buscarExpediente(7)."\n";

Patrn estructural - Proxy:

El patrn Proxy proporciona un objeto intermediario entre el cliente y el objeto a utilizar,


que permite configurar ciertas caractersticas (como el acceso) sin necesidad de modificar la
clase original.
Existen diferentes tipos de proxy:

16
Proxy remoto: proporciona un representante local de un objeto situado en otro
espacios de direcciones (en otro dispositivo conectado en red).
Proxy virtual: usados para crear objetos costosos slo cuando se soliciten.
Proxy de proteccin: permiten controlar el acceso a un objeto cuando es accesible o
no, dependiendo de determinados permisos.
Referencia inteligente: un sustituto de un puntero, que realiza operaciones
adicionales en el momento de accederse al objeto.

Se crear una interfaz Subject que define toda la funcionalidad que nuestro objeto ha de
proveer. Esta interfaz, es implementada por el objeto real. Se Crea tambin un Objeto Proxy
que mantiene una referencia al objeto real, y que adems implementa la interfaz Subject,
de modo que a la hora de precisar la funcionalidad sea indiferente si se est ejecutando el
Proxy o el objeto real.

Client: precisa de los servicios de Subject aunque trabaja con una referencia Proxy.
Proxy: Mantiene una referencia al objeto real adems de implementar la interfaz
Subject. El cliente trabajar con este objeto como si fuese el objeto real.
Subject: Interfaz que representa la funcionalidad que tanto el Proxy como el objeto
real deben implementar.
RealSubject: Objeto real que implementa la funcionalidad definida por la interfaz
Subject.

Consecuencias:
POSITIVAS: Segn el tipo de Proxy, las consecuencias positivas pueden ser:
Proxy remoto: oculta el hecho de que un objeto reside en otro espacio de
direcciones.

17
Proxy virtual: puede realizar optimizaciones, como la creacin de objetos
bajo demanda.
Proxy de proteccin y referencias inteligentes: permiten realizar diversas
tareas de mantenimiento adicionales al acceder a un objeto.
NEGATIVAS:
Introduce un nivel de indireccin adicional.

Ejemplo de uso:
En este caso vamos a hacer un ImageProxy que pospone la carga de los datos de una
imagen.

Clases->

<?php
/**
* Subject interface.
* Client depends only on this abstraction.
*/
interface Image
{
public function getWidth();

public function getHeight();

public function getPath();

/**
* @return string the image's byte stream
*/
public function dump();
}

/**
* Abstract class to avoid repetition of boilerplate code in the Proxy
* and in the Subject. Only the methods which can be provided without
* instancing the RealSubject are present here.
*/
abstract class AbstractImage implements Image

18
{
protected $_width;
protected $_height;
protected $_path;
protected $_data;

public function getWidth()


{
return $this->_width;
}

public function getHeight()


{
return $this->_height;
}

public function getPath()


{
return $this->_path;
}
}

/**
* The RealSubject. Always loads the image, even if no dump of the data
* is required.
*/
class RawImage extends AbstractImage
{
public function __construct($path)
{
$this->_path = $path;
list ($this->_width, $this->_height) = getimagesize($path);
$this->_data = file_get_contents($path);
}

public function dump()

19
{
return $this->_data;
}
}

/**
* Proxy. Defers loading the image data until it becomes really mandatory.
* This class does its best to postpone the very expensive operations
* such as the actual loading of the BLOB.
*/
class ImageProxy extends AbstractImage
{
public function __construct($path)
{
$this->_path = $path;
list ($this->_width, $this->_height) = getimagesize($path);
}

/**
* Creates a RawImage and exploits its functionalities.
*/
protected function _lazyLoad()
{
if ($this->_realImage === null) {
$this->_realImage = new RawImage($this->_path);
}
}

public function dump()


{
$this->_lazyLoad();
return $this->_realImage->dump();
}
}

/**

20
* Client class that does not use the data dump of the image.
* Passing blindly a Proxy to this class and to other Clients makes sense
* as the data would be loaded anyway when Image::dump() is called.
*/
class Client
{
public function tag(Image $img)
{
return '<img src="' . $img->getPath() . '" alt="" width="'
. $img->getWidth() . '" height="'
. $img->getHeight() . '" />';
}
}

Llamada->
$path = '/home/giorgio/shared/Immagini/kiki.png';
$client = new Client();

$image = new RawImage($path); // loading of the BLOB takes place


echo $client->tag($image), "\n";

$proxy = new ImageProxy($path);


echo $client->tag($proxy), "\n"; // loading does not take place even here

21
Patrones de comportamiento.

Estos patrones de diseo estn relacionados con algoritmos y asignacin de


responsabilidades a los objetos. Los patrones de comportamiento describen no solamente
patrones de objetos o clases sino tambin patrones de comunicacin entre ellos.

Patrones de comportamiento - Chain of responsability:

Permite establecer una cadena de objetos receptores a travs de los cuales se pasa una
peticin formulada por un objeto emisor. Cualquiera de los objetos receptores puede
responder a la peticin en funcin de un criterio establecido.
Este patrn desacopla a los emisores y a los receptores dndole a varios objetos la
posibilidad de tratar una peticin, que se pasa a travs de una cadena de objetos hasta que
es procesada por alguno de ellos.
Para reenviar la peticin a lo largo de la cadena, garantizando que los receptores
permanezcan implcitos, cada objeto de la cadena comparte una interfaz comn para
procesar peticiones y para acceder a su sucesor en la cadena.

22
Se usa cuando:
Hay ms de un objeto que puede manejar una peticin y el manejador no se conoce
a priori, sino que debera determinarse automticamente.
Se quiere enviar una peticin a un objeto entre varios sin especificar explcitamente
el receptor.
El conjunto de objetos que pueden tratar una peticin debera ser especificado
dinmicamente.

Manejador*: Define una interfaz para tratar las peticiones. Opcionalmente,


implementa el enlace al sucesor.
Manejador Concreto: Trata las peticiones de las que es responsable. Puede acceder a
su sucesor. Si el ManejadorConcreto puede manejar la peticin, lo hace; en caso
contrario la reenva a su sucesor.
Cliente: Inicializa la peticin a un objeto ManejadorConcreto de la cadena.

Ventajas:
Reduce el acoplamiento: Libera a un objeto de tener que saber que otro objeto
maneja una peticin. Ni el emisor ni el receptor se conocen y tampoco tienen que
conocer la estructura de la cadena.
Simplifica las interconexiones entre objetos. En vez de que los objetos mantengan
referencias a todos los posibles receptores, solo tienen una nica referencia a su
sucesor.
Aade flexibilidad para asignar responsabilidades a objetos : Se pueden aadir o
cambiar responsabilidades para tratar una peticin modificando la cadena en tiempo
de ejecucin.
Desventaja:
No se garantiza la recepcin: Dado que las peticiones no tienen un receptor explcito,
no hay garanta de que sean manejadas (la peticin puede alcanzar el final de la
cadena sin haber sido procesada). Una peticin tambin puede quedar sin tratar
cuando la cadena no est configurada correctamente.

23
Ejemplo de uso:

<?php

abstract class BasicHandler {


/** * @var Handler */
private $successor = null;
/** Sets a successor handler.
* * @param Handler $handler
*/
public function setSuccessor(Handler $handler) {
$this->successor = $handler;
}

/** * Handles the request and/or redirect the request


* to the successor.
* * @param mixed $request
* * @return mixed */
abstract public function handle($request);
}
class FirstHandler extends BasicHandler {
public function handle($request) {
//provide a response, call the next successor
}}
// .. code for SecondHandler and ThirdHandler classes .. $firstHandler = new
FirstHandler();
$secondHandler = new SecondHandler();
$thirdHandler = new ThirdHandler(); $firstHandler->setSuccessor($secondHandler);
$secondHandler->setSuccessor($thirdHandler);
$result = $firstHandler->handle($request);

Patrones de comportamiento - Iterator

Proporcionar una forma de acceder a los elementos de un objeto agregado de forma


secuencial sin exponer sus detalles. Con este patrn podemos recorrer los elementos de un
conjunto sin importar cmo se representen internamente.

24
Este patrn de diseo nos resultar til para acceder a los elementos de un array o
coleccin de objetos contenida en otro objeto.

Iterator: Interfaz que define las operaciones que podemos realizar sobre una
coleccin.
ConcreteIterator: Implementa las operaciones definidas por la interfaz Iterator.
Aggregate: Interfaz para crear objetos Iterator.
ConcreteAggregate: Implementa las operaciones que expone la interfaz Aggregate y
devuelve una instancia del iterador concreto en cuestin.

Ventajas
POSITIVAS:
Estandariza el tratado de elementos de listas con implementaciones independientes.
Permite variar el tratamiento de las listas modificando tan solo la clase que
implementa el iterador.
Se pueden realizar mltiples recorridos simultneos.
NEGATIVAS:
Aumenta la jerarqua de clases.

Patrones de comportamiento - Strategy:

El patrn nos permite decidir qu curso de accin debera tener un programa, basado en un
contexto especfico en tiempo de ejecucin. El programa encapsula dos algoritmos
diferentes dentro de dos clases y decide, en tiempo de ejecucin, que estrategia debe
seguir.

Ejemplo de uso:

25
Se tiene una clase que puede crear o actualizar el registro de un nuevo usuario. En ambos
casos se utilizan los mismos campos (name, address, mobile number, etc.); pero,
dependiendo de la situacin, tienes que usar funciones diferentes para cuando creas y para
cuando actualizas. Lo normal es que con una condicin if-else sea suficiente, sin embargo,
qu sucedera si se necesitara usar esta clase en un lugar diferente? En este caso, se
tendra que reescribir la misma condicin if-else, pero ac es donde se hace til un patrn.
No sera ms fcil especificar su contexto?

<?php
class User {
public function CreateOrUpdate($name, $address, $mobile,$userid = null)
{
if( is_null($userid) ) {
// Esto significa que el usuario an no existe, crear nuevo registro
} else {
// Esto significa que el usuario ya existe, actualizar por userid
}
}
}?>

Patrones de Arquitectura - Service Locator

Es un componente que contiene referencias a los servicios y encapsula la lgica que localiza
dichos servicios, este patrn es utilizado para obtener instancias de los servicios que
necesitamos.
Ventajas
* No instancia los servicios.
* Provee una manera de registrar servicios y mantener una referencia a dichos
servicios.
* Una vez que el servicio es registrado el service locator puede localizarlo.
* Debe proveer una forma de localizar un servicio sin especificar el tipo.

Desventajas

26
Cosas colocados en el registro son cajas negras con eficacia en lo que respecta al resto
del sistema. Esto hace que sea ms difcil de detectar y recuperarse de sus errores, y
puede hacer que el sistema en su conjunto menos fiable.
El registro debe ser nico, el cual puede hacer que sea un cuello de botella para las
aplicaciones concurrentes.
El registro puede ser un problema de seguridad grave, ya que permite a los forasteros
para inyectar cdigo correcto en una aplicacin.
El registro se esconde dependencias de la clase ', causando errores de tiempo de
ejecucin en lugar de errores en tiempo de compilacin cuando las dependencias que
faltan.
El registro hace que el cdigo ms difcil de probar, ya que todas las pruebas tienen
que interactuar con el mismo servicio de clase mundial localizador para establecer las
dependencias falsas de una clase bajo prueba.

Consecuencias
Resmenes complejidad
Proporciona acceso uniforme de servicio a los clientes
Facilita la adicin de componentes de negocio EJB
Mejora el rendimiento de la red
Mejora el rendimiento del cliente mediante el almacenamiento en cach
Patrones relacionados
SesinFachada
Fachada sesin utiliza un Service Locator para localizar y obtener la casa y referencias
remotas a los beans de sesin y beans de entidad, as como para localizar a un origen de
datos.

DataAccessObject
Un objeto de acceso de datos utiliza un Service Locator para buscar y obtener una referencia
a un origen de datos.

27
Inyeccion de Dependencias

La inyeccin de dependencias o DI por sus siglas en ingls, es una herramienta comnmente


utilizada en varios patrones de diseo orientado a objetos, consiste en inyectar
comportamientos a componentes.
Esto no es ms que extraer responsabilidades a un componente para delegarlas en otro,
estableciendo un mecanismo a travs del cual el nuevo componente pueda ser cambiado en
tiempo de ejecucin. Es conveniente no confundir Inyeccin de dependencias (DI) con
Inversin de Control (IoC), error muy comnmente cometido que figura especialmente en la
web. IoC es un tema para un prximo artculo.

La Inyeccin de Dependencias colo dentro de un objeto otros que puedan cambiar su


comportamiento, sin que esto implique volver a crear el objeto.
Esto nos permite tener un objeto que puede hacer un conjunto de tareas, cada una de esas
tareas es una responsabilidad, que puede ser ejecutada por otro objeto nicamente
especialista y dedicado a ello [una responsabilidad], pero ahora tenemos otro diferenciador,
El objeto responsable de ejecutar esa nica tarea
Puede establecerse en tiempo de ejecucin
La implementacin habitual en programacin es crear un mtodo capaz de establecer el
comportamiento, es decir capaz de cambiar el valor de un atributo asignndole una
instancia de objeto diferente.

28
Active Record

Este patrn de persistencia es quizs uno de los ms habituales y es usado por frameworks
como Rails. La idea detrs del patrn es bastante sencilla. Se trata de una clase que se
encarga de implementar todas las operaciones de consulta y modificacin de una tabla
concreta de la base de datos.

De esta forma nuestra aplicacin quedar completamente aislada del trabajo con SQL ya
que delegar en la capa de componentes ActiveRecord para realizar todas las operaciones.

29
Este patrn de diseo en un primer momento parece suficiente para abordar la mayor parte
de las problemticas. Sin embargo hay situaciones en las que necesitamos algo ms de
flexibilidad y capacidad de adaptacin. Para ello existe el patrn DAO o Data Access Object.

Data Access Object

Este patrn de diseo divide ms las responsabilidades en la aplicacin de tal forma que
tendremos unas clases que se encargaran de la lgica de negocio y otras clases la
responsabilidad de persistencia.

30
Aislamiento y Flexibilidad

A veces es difcil decidir que patrn de diseo elegir para nuestra casustica. Cuanto mayor
flexibilidad necesitemos en la capa de persistencia ms nos encajar el uso de un patrn
DAO. Cuanto mas aislada este la aplicacin y menos flexibilidad necesite ms nos encajar
un Active Record. Por poner un ejemplo sencillo imagenemos que el concepto de Factura es
necesario para un mdulo diferente de la aplicacin que se encarga de imprimir PDFs con
los datos de la Factura. En este caso no estamos en una situacin de aislamiento sino en lo
contrario. El mdulo que se encarga de imprimir la factura trabajara de una forma ms
comoda con business objects sencillos que con Active Records. Por lo tanto es una casustica
en la que encajar mejor el patrn DAO que el ActiveRecord.

31
Como vemos el Active Record tiene un conjunto de mtodos que no vamos a utilizar ya que
solo necesitamos los de un Business Object.

32
33
Patrones en Symfony

https://speakerd.s3.amazonaws.com/presentations/f55c3940b4c20131d8ef7625813d8974/D
esign-Patterns-Symfony.pdf

Factory Method: Define una interface para crear objetos, pero deja que la subclase decida
que clase instanciar.

Form Component - Resolviendo herencia de tipos.

34
35

Вам также может понравиться