You are on page 1of 92

Patrones de Diseo

Introduccin

Introduccin a Patrones de Diseo


Alguien ha resuelto ya tus problemas
El por qu y el cmo podemos explotar la
sabidura y lecciones aprendidas por otros
desarrolladores que han pasado por los mismos
problemas de diseo y han sobrevivido
Beneficios de los patrones de diseo
Veremos algunos principios OO clave
La mejor manera de usar patrones es cargarlos
en tu mente y reconocer lugares en tu diseo y en
aplicaciones existentes donde poder aplicarlos
No se reutiliza cdigo, se reutiliza experiencia

Todo empieza con un simple juego


Joe trabaja para una
compaa que se dedica a
crear juegos de simulacin
de estanques de pato.
El juego muestra una gran
variedad de especies,
nadando y haciendo
graznidos.
El diseador inicial del
sistema utiliz tcnicas
estndares OO y cre una
superclase Pato de la cual
las subclases de Pato
heredan

Todo empieza con un simple juego


Todos
lo
y graz s patos nad
nan, l
an
a
s u p er
clase
s e en c
de la
a
imple
menta rga
cin

El mtodo Mostrar() es
Abstracto, ya que
todos los subtipos de
Pato se ven de manera
distinta

Ca d a
su
respon btipo es
s
imple able de
m ent a
el
mtod
o M os
t r a r ()

Muchos otros tipos de


patos heredan de la
clase Pato

Todo empieza con un simple juego


En el ltimo ao, la compaa ha tenido
bastante presin debido a sus
competidores.
Despus de una lluvia de ideas, los
ejecutivos de la compaa piensan que
es hora de innovar.
Ellos necesita algo realmente
sorprendente para mostrar en la reunin
de inversionistas la prxima semana

Ahora necesitamos que los patos


VUELEN
Los ejecutivos decidieron que patos voladores
es justamente lo que esta aplicacin necesita
para vencer a sus competidores.
Y por supuesto, la jefa de Joe les dijo que no
era problema para Joe, y que terminara en
una semana.
Despus de todo dijo la jefa
Joe es un programador OO
Qu tan difcil puede ser?

Ahora necesitamos que los patos


VUELEN
Solo necesito aadir un nuevo
mtodo llamado Volar() a la
clase Pato y los dems
heredarn automticamente.
Ahora es mi oportunidad para
mostrar realmente mi genialidad
en la programacin OO

Lo que queremos

Ahora necesitamos que los patos


VUELEN

Todas
la
subcla s
s e s he
redan
Volar(
)
agreg
Lo que Joe

s de Pato
Otros tipo

Pero algo sali mal muy mal

Joe, estoy en la reunin de


inversionistas, estamos
revisando el demo del juego, y
hay Patos de Goma volando
por todos lados. Es una broma o
que?

Qu pas?
Joe nunca not que no
todas las subclases de
pato deben Volar.
Cuando Joe agreg
nuevo comportamiento
a la superclase,
tambin estaba
agregando
comportamiento no
apropiado a las
subclases. Ahora tiene
objetos inertes volando
en el juego.

Una
actualizaci
n localizada
al cdigo
caus un
efecto
secundario
no local
(patos de
goma
voladores)

Qu pas?
to
amien
t
r
o
p
el com perclase,
Poner
su
) en la d de vuelo
(
r
a
l
o
V
da
habili
,
le dio S los patos no
e
O
u
D
a TO
a los q
o
d
n
e
incluy n hacerlo
a
deber

Patos de goma no
graznan, el
comportamiento es
sobrescrito a Chillar

Qu pas?
OK, hay una pequea
falla en mi diseo. No
se por qu no le
pueden llamar una
nueva funcin. Es
simptico

Lo que l pens que


era un buen uso de
herencia con el
propsito de
reutilizacin no
result tan bueno
cuando lidiamos con
mantenimiento

Joe piensa en herencia


Podra sobrescribir
Volar() en el pato de
goma como lo hice
con Graznar

Joe piensa en herencia


Pero que pasara si
aumentamos patos
seuelo de madera
en el futuro. Ellos no
vuelan ni graznan
Esta es otra clase
posible en la
jerarqua; y notemos
que al igual que el
pato de goma,
tampoco vuela, pero
tampoco grazna

Ejercicio
De las siguientes opciones elija cules serian las
desventajas de utilizar herencia en el ejemplo anterior
A. El cdigo se duplica en las subclases
B. Cambios en tiempo de ejecucin son difciles
C. No podemos hacer que los patos bailen
D. Se complica obtener conocimiento del comportamiento
de todos los patos
E. Los patos no pueden volar y graznar al mismo tiempo
F. Los cambios en el cdigo podran afectar a otros patos sin
intencin

Y si usamos una Interfaz?


Joe se dio cuenta que la herencia probablemente no
era la respuesta. Recibi un memo de los ejecutivos
diciendo que quieren actualizar el producto cada seis
meses (de maneras que ellos an no han decidido)
Joe sabe que las especificaciones seguirn cambiando
y ser forzado a revisar y probablemente actualizar
Volar() y Graznar() por cada subclase de Pato que se
vaya a crear para siempre!
l necesita una manera ms limpia de hacer que
solamente algunos ( no todos) los tipos de patos
vuelen y graznen

Y si usamos una Interfaz?


Podra sacar el mtodo Volar()
de la superclase Pato y hacerla
una interfaz de esa manera
nicamente los patos que
quieran volar implementan la
interfaz y de paso hago otra
interfaz para Graznar ya que no
todos los patos graznan

Que opinas de este diseo?


Es la idea ms tonta que se te
ha ocurrido. Cdigo
Duplicado. Si creas que
sobrescribir unos cuantos
mtodos era un error, cmo te
sentirs cuando tengas que
cambiar el comportamiento de
vuelo de las 48 subclases de
pato?

Qu haras t si fueras Joe?


Sabemos que no todas las subclases
deben tener comportamiento de vuelo y
graznido as que implementar herencia no
es la respuesta correcta.
Y mientras que las interfaces IVolar e
IGraznar resuelven parte del problema
(Ej: patos de goma no vuelan), estas
destruyen la reutilizacin del cdigo para
esos comportamientos creando otra
pesadilla diferente de mantenimiento.
Por supuesto puede haber ms de un tipo
de vuelo, incluso entre patos que si

Qu haras t si fueras Joe?


En estos momentos debemos estar
esperando que un Patrn de Diseo llegue
cabalgando en un caballo blanco a salvar
el da Pues No, qu diversin habra en
ello?
Vamos a solucionar las cosas a la manera
antigua, aplicando buenos principios
de diseo OO

No sera hermoso si existiera una


manera de construir software que
cuando se necesiten hacer
cambios, lo podamos hacer con el
menor impacto posible en el
cdigo existente? Podramos pasar
menos tiempo arreglando cdigo y
ms tiempo haciendo que el
programa haga cosas nuevas y
mejores

Cul es la nica cosa con la que


puedes contar en el desarrollo de
software?

EL CAMBIO
Utilizar un espejo para ver la respuesta

La constante en desarrollo de
software
No importa
No importa
No importa
No importa
aplicacin

dnde trabajes
qu construyes
qu lenguaje utilices
qu tan bien diseada este una

Con el tiempo una aplicacin debe


crecer y cambiar o sino morir

Ejercicio
Muchas cosas pueden crear cambios. Pensemos
en razones que hayan disparado este
comportamiento en nuestras aplicaciones. Ej:
Mis clientes o usuarios decidieron que queran algo
diferente o nueva funcionalidad
Mi compaa decidi comprar una nueva base de datos y
tambin est comprando datos de proveedores en otro
formato. Argh!

Enfocarse en el problema
Ahora sabemos que el uso de la
herencia no funcion muy bien, ya que
el comportamiento de pato sigue
cambiando en todas sus subclases y no
es apropiado que todas las subclases
tengan esos comportamientos.
Las Interfaces sonaban prometedoras al
principio solo patos que deban volar
Volarn- pero como en las interfaces no
se implementa cdigo, no existe la
reutilizacin de cdigo.

Enfocarse en el problema
Y esto quiere decir, que cuando se
necesite modificar un comportamiento,
estamos forzados a rastrear y
cambiarlo en todas las diferentes
subclases donde ese comportamiento
se haya definido (probablemente
introduciendo nuevos errores en el
camino!)
Por suerte, hay un principio de diseo
justamente para estas situaciones

Principio de diseo
Identifica los aspectos de
tu aplicacin que varan y
sepralos de aquellos que
permanecen igual

Nuestro primer principio de


diseo. (aunque ya fue visto
en otra poca)

Enfocarse en el problema
En otras palabras, si tenemos algn aspecto de nuestro
cdigo que est cambiando, por ejemplo nuevos
requerimientos, entonces sabremos que existe un
comportamiento que necesita ser extrado y separado de
todo lo que no cambia.
Otra manera de pensarlo es: tomar las partes que varan
y encapsularlas, para que despus se puedan alterar
o extender sin afectar a las partes que no varan.
A pesar de ser un concepto simple, forma la base de casi
todo patrn de diseo. Todos los patrones proveen una
manera de dejar que algunas partes de un sistema varen
independientemente de las dems.

Toma las partes que


varan y
encapslalas para
que as no afecten
al resto de tu
cdigo.
El resultado?
Menos
consecuencias no
intencionales al
cambiar cdigo y
ms flexibilidad en
tus sistemas

Separando lo que cambia de lo


que se queda igual
Dnde empezamos? Segn lo visto, aparte de los
comportamientos Volar() y Graznar(), la clase Pato
funciona bien y parece que no hay otras partes de ella
que varen o cambien frecuentemente.
As que, aparte de algunos cambios, vamos a dejar a
la clase pato en paz.
Ahora, para separar las partes que cambian de
aquellas que no, vamos a crear dos conjuntos de
clases (separadas totalmente de Pato), una para
Volar y otra para Graznar.
Cada conjunto de clases representar las
implementaciones de su comportamiento respectivo.
Por ejemplo, una clase implementa graznar, otra
implementa chillar y otra implementa silencio

Separando lo que cambia de lo


que se queda igual
Sabemos que Volar() y Graznar() son las
partes de la clase Pato que varan entre los
patos
Para separar estos comportamientos de la
clase Pato, sacaremos ambos mtodos de
la clase Pato y crearemos nuevas clases
para representar cada comportamiento

Separando lo que cambia de lo que


se queda igual
la
es an s
o
t
a
P
se
s lo
La cla se de todo los
s
cl a
super ero sacamo s
lo
p
patos, amientos y
t
r
compo s en otra
o
s
ponem ra de clase
tu
estruc

Varias implementaciones
de comportamientos
vivirn aqu

Ahora
V
cada u olar y Grazn
n
a
conjun a tiene su p r
ropio
to de
clases

Diseando los comportamientos de


Pato
Cmo vamos a disear un conjunto de clases que
implementen los comportamientos de volar y
graznar?
Debemos mantener las cosas flexibles, despus de todo,
fue la inflexibilidad en los comportamientos de los patos
la que nos meti en problemas en primer lugar
Sabemos que debemos asignar comportamientos a las
instancias de Pato, por ejemplo, tal vez queramos
instanciar un nuevo pato de goma y darle un tipo de
comportamiento de vuelo especfico al iniciarlo

Diseando los comportamientos de


Pato
Y ya que estamos por all, por qu no asegurarnos de
poder cambiar este comportamiento dinmicamente?
En otras palabras, debemos incluir mtodos o
propiedades de asignacin en la clase Pato para que
podamos cambiar los comportamientos de las subclases
en tiempo de ejecucin
Dados estos objetivos, veamos el segundo principio de
diseo

Principio de diseo

Programa a una interfaz


no una implementacin

Diseando los comportamientos de


Pato
Utilizaremos una interfaz para representar cada
comportamiento, por ejemplo Vuelo y Graznido y cada
implementacin de un comportamiento va a
implementar una de estas interfaces
Entonces, esta vez no ser la clase Pato ni sus
subclases las que implementarn las interfaces de
vuelo y graznido. En lugar de ello crearemos un
conjunto de clases cuya nica razn de existir es la de
representar un comportamiento (por ejemplo
Chillar), y son estas clases en lugar de los patos, las
que implementarn el comportamiento de una interfaz

Diseando los comportamientos de


Pato
Esto contrasta bastante la manera como hemos estado
trabajando hasta ahora, donde un comportamiento
proviene de una implementacin concreta en la superclase
Pato, o dando una implementacin especializada en la
misma subclase. En ambos casos estbamos a expensas de
una implementacin.
Estbamos encerrados al tratar de utilizar la
implementacin especfica y no haba espacio para un
cambio de comportamiento (excepto escribir ms cdigo)
Con nuestro nuevo diseo, las subclases de Pato utilizarn
un comportamiento representado por una interfaz
(IGraznido e IVuelo), pero la implementacin real del
comportamiento, es decir, el cdigo del comportamiento
concreto, no estar encerrada en las subclases de Pato

Diseando los comportamientos de


Pato

De ahora en adelante,
los comportamientos
de un Pato van a vivir
en una clase separada
una clase que
implementa una
interfaz de
comportamiento
particular.
De esa manera, las
subclases de Pato no
necesitarn conocer
ningn detalle de
implementacin para

No veo por qu tenemos


que utilizar una interfaz
para el comportamiento de
Vuelo. Podemos hacer
exactamente lo mismo con
una superclase abstracta.
No era el objetivo utilizar
polimorfismo?

Programar a una interfaz significa


programar a un supertipo
La palabra interfaz est sobrecargada aqu ya que existe el concepto
de interface, y existe el constructo interface para los lenguajes OO.
Podemos programar a una interfaz, sin necesidad de usar una ya
que el objetivo es explotar el polimorfismo programando a un supertipo
y de esa manera el objeto real que es ejecutado no quede encerrado en
el cdigo
Podramos volver a escribir el principio Programar a un Supertipo de la
siguiente manera :
El tipo (de datos) de las variables declaradas debera ser un supertipo,
generalmente una clase abstracta o una interfaz, para que los objetos
asignados a estas variables puedan ser de cualquier implementacin
concreta del supertipo, lo que significara que la clase que las declara (a
las variables) no tienen que conocer los tipos de objetos reales!
Tal vez ya sepas esto, pero para estar seguros de que todos estamos en
hablando de lo mismo

Simple ejemplo - Polimorfismo


Este es un ejemplo de
como utilizar un tipo
polimrficamente.

Supertipo Abstracto
(puede ser una clase
abstracta o una
interfaz

Imagina una clase


abstracta Animal, con dos
implementaciones
concretas, Perro y Gato

Implementaciones
concretas

Simple ejemplo - Polimorfismo


Programar a una implementacin sera:
Perro p = new Perro();
p.Ladrar();

Declarar la
variable p
como tipo
Perro (una
implement
acin conc
de Animal)
reta
nos hace c
odificar a u
implement
na
acin conc
reta a la
fuerza

Simple ejemplo - Polimorfismo


Pero Programar a una interfaz/supertipo sera:
Sabemos que es un
perro, pero podemos
Animal animal = new Perro();
utilizar la referencia
Animal.HacerUnSonido(); animal
Polimrficamente

Simple ejemplo - Polimorfismo


Mejor an, en lugar de escribir a la fuerza la
instanciacin del subtipo (new Perro()), asigna la
implementacin concreta en tiempo de ejecucin
Animal animal = Obtener
animal.HacerUnSonido();

No sabemos QU
animalsea todo lo
que nos importa es
Animal();
que sepa hacer un
sonido

Implementar los comportamientos


del Pato IVuelo es una interfaz que
De igual manera
todas las clases de vuelo
implementan. Todas las
nuevas formas de vuelo
necesitan implementar el
mtodo Volar

Esta es la
implementacin de
vuelo para todos los
patos que tienen
alas

Y esta es la
implementacin
para los patos que
no vuelan

para el
comportamiento de
graznido

Implementar los comportamientos


del Pato

Con este diseo, otros objetos pueden


reutilizar Volar y Graznar ya que estos
comportamientos no estn escondidos
dentro de los Patos!
Podemos aumentar nuevos
comportamientos sin modificar ningn
otro ya existente o tocar ninguna clase
Pato que utiliza estos
comportamientos

r que
Es deci
mos los
e
n
e
t
b
o
ios de
sin la
benefic
N

I
C
A
IZ
on la
c
REUTIL
e
n
e
i
ue v
carga q
ia
herenc

Debo implementar mi aplicacin primero, ver donde


cambian las cosas y luego regresar y separar/encapsular
esas cosas?

No siempre; generalmente cuando estamos


diseando una aplicacin, anticipamos estas
reas que van a variar y luego construimos el
cdigo que hace ganar flexibilidad.
Nos daremos cuenta que los principios y patrones
pueden ser aplicados en cualquier etapa del ciclo
de desarrollo

Debemos hacer Pato una interfaz


tambin?
En este caso no.
Como veremos ms adelante una vez que
tengamos todo junto, nos beneficiaremos
teniendo a Pato como Clase y sus subtipos , como
Pato Colorado, heredando los mtodos y
propiedades comunes.
Ahora que hemos quitado lo que vara de la
herencia de Pato, obtenemos los beneficios de
esta estructura sin los problemas que conllevan.

Se siente extrao tener una clase que solo sea un


comportamiento. No se supone que las clases
representan cosas? No se supone que las clases
tienen estados y comportamientos?

En un sistema OO, s, las clases representan


cosas que generalmente tienen estados ( las
variables de instancia) y mtodos.
Y en este caso, las cosas que representa es un
comportamiento. Pero inclusive un
comportamiento puede tener estado y mtodos;
un comportamiento de vuelo podra tener
variables de instancia representando los atributos
del comportamiento vuelo (aletazos por minuto,
altitud mxima, velocidad, etc)

Ejercicio
Usando el diseo anterior, qu tenemos que
hacer si necesitamos volar con propulsor?
Una clase que podra utilizar el comportamiento
graznar

Integrando el comportamiento de
Pato
La clave es que un Pato ahora
delegar sus comportamientos de
vuelo y graznido, en lugar de usar
mtodos definidos en la misma clase
Pato ( o subclase)

Integrando el comportamiento de
Pato Primer Paso
Primero agregamos dos variables a la clase Pato
llamadas Vuelo y Graznido como interfaces (no
implementaciones concretas)
Cada objeto pato le dar valor a estas variables
polimrficamente para referenciar el comportamiento
especfico que desee en tiempo de ejecucin (volar con
alas, chillar, etc)
Tambin quitamos los mtodos volar y graznar de la clase
Pato (y cualquier subclase) ya que hemos movido estos
comportamientos a las clases comportamiento de vuelo y
graznido
Reemplazaremos los mtodos Volar y Graznar en la clase
Pato con dos mtodos similares llamados IniciarGraznido
e IniciarVuelo(), luego veremos cmo los utilizaremos

Integrando el comportamiento de
Pato Primer Paso
Las variables que
representan
comportamiento son
declaradas como
comportamientos de
tipo INTERFAZ

Estos mtodos
reemplazan a
Volar() y
Graznar()

Las variables instancia mantienen


una referencia a un
comportamiento especfico en
tiempo de ejecucin

Integrando el comportamiento de
Pato - Segundo
Implementamos los mtodos
Para graznar, un Pato solo le permite al objeto referenciado en la
variable que haga la operacin
No importa que tipo de objeto sea, nicamente nos interesa
que sepa graznar
Cada Pato tiene una referencia a
algo que implementa la interfaz
IGraznido
En lugar de manejar el
comportamiento de Graznar por si
mismo, el objeto Pato delega ese
comportamiento al objeto
referenciado por el
comportamiento IGraznido

Integrando el comportamiento de
Pato - Tercero
Ok, es hora de preocuparnos cmo se asignan los valores
de las variables Vuelo y Graznido

Recordemos que este pato hereda


sus instancias de comportamiento
de la clase Pato

Un Pato Gargantilla
utiliza la clase
GraznarNormalmente
para manejar sus
graznidos, por eso
cuando la operacin
IniciarGraznido() es
llamado, la
responsabilidad es
delegada al objeto
GraznarNormalmente
y obtenemos un hermoso
graznido

Integrando
Entonces el graznido de un pato colorado es tan real
como el de cualquier pato, no es un chillido, no es un
silencio. Entonces qu pas aqu?
Cuando un PatoColorado es instanciado, su constructor
inicializa su variable de comportamiento de graznido
heredada a una nueva instancia de
GraznarNormalmente (que es una implementacin de
IGraznido)
Lo mismo es cierto para el comportamiento de
vuelo

Un momento, no habamos dicho


que NO debemos programar a una
implementacin? Y qu estamos
haciendo en ese constructor?
Estamos haciendo una nueva
referencia a la clase concreta
GraznarNormalmente!

Bien observado, eso es exactamente lo que estamos


haciendo por ahora.
Ms adelante conoceremos ms patrones que nos ayudarn a
arreglar este problema.
An as, notemos que asignando los comportamientos a una
clase concreta (instanciando una clase comportamiento como
GraznarNormalmente y la asignamos a nuestra variable),
podramos fcilmente cambiarlo en tiempo de ejecucin.
Y por ende, an tenemos mucha flexibilidad, lo nico malo es
que estamos realizando un trabajo muy pobre al inicializar las
variables de manera flexible. Pero si lo pensamos un poco, y
notamos que nuestras variables de comportamiento son de
tipo interfaz, podramos (a travs de la magia del
polimorfismo) asignar dinmicamente un comportamiento
distinto en tiempo de ejecucin.
Tomemos un tiempo y pensemos cmo implementaramos un
pato para que su comportamiento pueda cambiar en tiempo de
ejecucin

Ejercicios
Crear y compilar la clase Pato y una clase que herede
de ella (Pato Gargantilla por ejemplo)
Crear y compilar las interfaces de comportamiento y
dos implementaciones para vuelo y tres para graznido
Crear una clase de prueba donde se compruebe el
cdigo.
Darle un valor de forma dinmica a una prueba (vuelo o
graznido)

Vista panormica de los


comportamientos encapsulados
Ok, ahora que hemos tocado el diseo del simulador, es
hora de regresar al inicio y mirar la panormica.
A continuacin veremos la estructura de clases. Tendremos
todo lo que estamos esperando: patos extendiendo Pato,
comportamientos de vuelo implementando IVuelo y
comportamientos de graznido implementando Igraznido.
Notemos tambin que hemos empezado a describir las
cosas un poco diferente. En lugar de pensar en
comportamientos de patos como un conjunto de
comportamientos, ahora lo pensamos como una familia de
algoritmos.

Vista panormica de los


comportamientos encapsulados
Pensndolo un poco, los algoritmos representan las
cosas que un pato podra hacer (diferentes maneras de
graznar o volar), pero podramos as mismo utilizar la
misma tcnica para un conjunto de clases que
implementan las diferentes maneras de calcular los
impuestos de ventas por pas.
Prestemos mucha atencin a las relaciones entre las
clases. De hecho podemos ir corrigiendo las relaciones
apropiadas (Es-un/a, Tiene-un/a e implementa) en cada
flecha del diagrama

Comportamiento encapsulado

Un Cliente utiliza una


familia de algoritmos
encapsulada para graznar
y volar

to s
n
e
mi

a
ort n
p
com os so
s
s
o
Est oritm iable
b
g
al rcam
inte

Tiene-un puede ser mejor que Es-un


La relacin TIENE UN es muy interesante, cada pato
tiene una variable de comportamiento de vuelo y
graznido al cual se le delegan las operaciones volar y
graznar
Cuando unimos clases de esta manera estamos usando
composicin. Los patos son compuestos con el objeto
de comportamiento correcto, en lugar de heredarlo
sta es una tcnica importante, y de hecho, ya estamos
usando nuestro tercer principio de diseo:

Principio de diseo

Favorecer a la composicin
sobre la herencia

Tiene-un puede ser mejor que Es-un


Como hemos visto, crear sistemas utilizando
composicin nos da mucha ms flexibilidad. No solo
permite encapsular familia de algoritmos en su propio
conjunto de clases, sino que te permite cambiar
comportamientos en tiempo real mientras los
objetos que estemos componiendo implementen la
interfaz de comportamiento correcta.
La composicin se utiliza en muchos patrones de diseo
y veremos algunas de sus ventajas y desventajas ms
adelante

Maestro y Estudiante
Maestro: Saltamontes, dime qu has aprendido de las
maneras Orientadas a Objeto.
Estudiante: Maestro, he aprendido que la promesa de
la orientacin a objeto es la reutilizacin.
Maestro: Saltamontes, continua
Estudiante: Maestro, a travs de la herencia todas las
cosas buenas pueden ser reutilizadas y de esa manera
podemos cortar el tiempo de desarrollo como cortar
bamb en el bosque.
Maestro: Saltamontes, se desperdicia ms tiempo en
el cdigo antes o despus de que se complete el
desarrollo?
Estudiante: La respuesta es despus, Maestro.
Siempre gastamos ms tiempo manteniendo y
cambiando el software que al inicio.
Maestro: Entonces saltamontes, debera el esfuerzo
enfocarse en la reutilizacin por encima de la
mantenibilidad y extensibilidad?
Estudiante: Maestro, yo creo que hay verdad en eso.
Maestro: Puedo ver que an tienes mucho que
aprender. Quiero que vayas a meditar sobre la herencia

Ejercicio
Reclamo es un dispositivo que los cazadores utilizan
para imitar el llamado de los patos (graznido). Cmo
implementaramos un reclamo que NO herede de la
clase Pato?

Hablando de patrones de diseo


Felicitaciones
en tu primer
patrn
Hemos aplicado nuestro primer patrn de diseo el
patrn STRATEGY. As es, ya hemos utilizado el patrn
Strategy para rehacer el juego de estanque.
Gracias a este patrn, el simulador est listo para
cualquier cambio gerencia quiera realizar prximamente.
Y ahora que tomamos el camino largo para aplicarlo,
aqu est la definicin formal de este patrn:

El patrn Strategy

El Patrn Strategy define una familia de


algoritmos, encapsula cada uno de ellos, y
los hace intercambiables. Strategy deja
que los algoritmos varen
independientemente de los clientes que lo
utilizan.
Utiliza ESTA definicin
cuando quieras
impresionar a tus amigos o
quieras influenciar a un
ejecutivo

Rompecabezas
En el siguiente ejemplo
encontraremos clases e
interfaces desordenadas
pertenecientes a un juego de
aventuras, clases de
personajes y comportamiento
de armas que cada personaje
puede usar en el juego. Cada
personaje puede hacer uso de
un arma a la vez, pero puede
hacer el cambio de armas en
cualquier momento durante
el juego. Tu debes arreglar
todo

Ordenar las clases

Identificar una clase abstracta, una interfaz y ocho clases

Dibujar flechas entre las clases

Herencia
Interfaz
Tiene un

Colocar el mtodo setArma() (o el Set de la propiedad Arma)


en la clase correcta

Rompecabezas

Necesito una porcin de queso crema


y mermelada en pan blanco, un
helado de vainilla con decorado de
chocolate, un sndwich de queso a la
parrilla con tocino, una ensalada de
atn con pan tostado, un helado
banana Split con dos bananas y un
caf con crema y dos cucharadas de
azcar, oh y tambin coloca una
hamburguesa en la parrilla!
Alice

Flo
Dame un QJ. En
Blanco, y Blanco y
negro, un Jack
Benny, una radio, y
un bote de casa, un
caf regular y una
parrilla

Conversacin en un restaurante local

Cul es la diferencia entre las dos


conversaciones?
Nada! Son exactamente la misma orden, excepto que
la primera persona est utilizando el doble de palabras
y tentando la paciencia de el cocinero.
Qu tiene Flo que no tenga Alice? Un vocabulario
compartido con el cocinero impaciente. No solo es ms
fcil la comunicacin con el cocinero, sino que le hace
recordar menos cosas pues l tiene todos los patrones
del restaurant en su cabeza.
Los patrones de diseo nos dan un vocabulario
compartido con otros desarrolladores. Una vez que
tengamos el vocabulario podemos comunicarnos ms
fcilmente con otros desarrolladores e inspirar a otros
que no los conocen a aprenderlos. Tambin eleva
nuestro pensamiento arquitectnico dejndonos pensar
al nivel de patrn, y no a nivel de objeto

Acabo de crear una clase Broadcast.


Mantiene el rastro de todos los objetos
escuchndolos y en cualquier momento
que os datos lleguen les manda un
mensaje a todos los que lo escuchan. Lo
mejor de todo es que se pueden
registrar en cualquier momento ellos
mismos es muy dinmico

Rick, por qu no
dices solamente
que ests utilizando
el patrn Observer

Exactamente. Si te
comunicas en
patrones, entonces
otros desarrolladores
sabrn inmediata y
precisamente el
diseo que estas
describiendo.

Ejercicio
Puedes pensar en vocabularios que sean usados en
otros lugares?
Que cualidades son comunicadas?
Que cualidades se comunican junto a los nombres de
los patrones?
Que cualidades se comunican cuando decimos patrn
strategy?

El poder de un vocabulario
compartido
Cuando nos comunicamos utilizando patrones,
hacemos ms que solamente compartir un LINGO.

Vocabularios compartidos de patrones son


PODEROSOS. Cuando nos comunicamos con
otros desarrolladores o nuestro equipo
utilizando patrones, estamos comunicando no
solo el nombre del patrn sino un conjunto de
cualidades, caractersticas y restricciones que
tegy para
a
tr
S
n
r
t
a
esos patrones representan.
s el p
ientos de
Utilizamo
comportam

r los varios
e que los
ic
d
implementa
s
o
n
to
atos es
ido
nuestros p
pato han s
l
e
d
s
to
n
ie
de clases
m
s
o
ta
p
r
u
o
r
p
g
m
o
io
c
op
s en sus pr
o
d
la
u
s
andidos y
p
p
a
x
c
e
e
en
t
n
e
n
s ser fcilm
de ejecuci
o
p
m
e
que puede
ti
n
e
, inclusive
cambiados
ario.
si es neces

Los patrones nos permiten decir ms con


menos. Cuando utilizamos un patrn en una
descripcin, otros desarrolladores rpidamente
conocen precisamente el diseo que tenemos en
mente

o
nes de dise
io
s
u
c
is
d
o
uniones
dan
Cuntas re
e se degra
n?
u
q
o
id
d
n
lementaci
p
im
e
d
hemos ate
s
e
ll
te en deta
rpidamen

Hablar al nivel de patrones nos permite


quedarnos en el diseo ms tiempo. Hablar
de sistemas de software utilizando patrones nos
permite mantener la discusin a nivel de diseo,
sin tener que bajarnos al nivel de detalles de
implementacin de objetos y clases

Vocabularios compartidos pueden turbo


cargar al equipo de desarrollo. Un equipo
bien educado en patrones de diseo puede
moverse ms rpidamente con menos rea para
el malentendido

compartir
a
a
z
n
ie
m
co
s
stro equipo
e
u
n
en trmino
o
d
s
n
ia
a
c
n
Cu
ie
r
e
de
eo y exp
comunidad
a
n
u
ideas de dis
e
y
u
s, se constr
de patrone
patrones
usuarios de

Vocabularios compartidos alienta a los


desarrolladores junior a actualizarse. Los
desarrolladores junior buscan a los experimentados.
Cuando los senior utilizan patrones de diseo, los
junior se motivan a aprenderlos. Se recomienda
construir una comunidad de usuarios de patrones
e estudio
d
o
p
ru
g
n
en la organizacin o centro educativo
ru
en empeza
n, a veces
Pensemos
organizaci
a
tr
s
e
u
n
n
se
de patrone
paga por
r
e
n
te
b
o
s
mo
hasta pode
;)
aprender

Cmo puedo usar los patrones de


diseo?
Todos usamos frameworks como .Net o Java API. Los
tomamos y escribimos cdigo a su API, compilamos y
creamos programas aprovechando el cdigo que alguien
ms ha escrito. Libreras y Frameworks van junto al
modelo de desarrollo donde podemos escoger y usar
componentes y enchufarlos directamente. Pero no nos
ayudan a estructurar nuestras aplicaciones para que
sean ms fciles de entender, mantener y al mismo
tiempo flexibles
Patrones de diseo no van directamente en el cdigo,
sino en tu cabeza, y una vez familiarizado con ellos
podremos aplicarlos en nuestros nuevos o antiguos
diseos

Un montn de patrones

Nuestro
CEREBRO

Nuestro cdigo,
ahora nuevo y
mejorado con
patrones de
diseo

Si los patrones son tan grandiosos, por


qu alguien no construye una librera de
ellos para no hacerlo yo?
Los patrones de diseo estn en un nivel ms alto que
las libreras.
Los patrones de diseo nos dice cmo estructurar clases
y a objetos para resolver ciertos problemas y es nuestro
trabajo adaptar esos diseos para que encajen en
nuestra aplicacin en particular

Las libreras y frameworks no son


tambin patrones de diseo?
Frameworks y libreras nos son patrones de diseo;
proveen implementaciones especficas que nosotros
vinculamos a nuestro cdigo.
A veces, sin embargo, las libreras y frameworks utilizan
patrones de diseo en sus implementaciones.
Y eso es grandioso, pues una vez que entendemos los
patrones de diseo, entenderemos ms rpidamente los
APIs que se han estructurado desde estos patrones

Entonces, no existen libreras de


patrones de diseo?
No, pero aprenderemos despus acerca de catlogos de
patrones con listas de patrones que podemos aplicar a
nuestra aplicacin

Patrones no
son ms que
la utilizacin
de principios
de diseo
OO
Un error muy
comn,
Saltamontes,
pero es ms sutil
que eso. Tienes
mucho que
aprender

Desarrollador
Escptico

Gur amistosa de
patrones

Desarrollador: Ok, hmm, pero no es todo esto acerca del buen


diseo OO; o sea que mientras yo siga el encapsulamiento y conozca
sobre abstraccin, herencia y polimorfismo, no necesito pensar en
patrones de diseo? No es ms sencillo de lo que parece? no es por
eso que he recibido todas esas clases de OO? Pienso que los patrones
son tiles para las personas que no conocen el buen diseo OO.
Gur: Ah, este es uno de los verdaderos malentendidos del desarrollo
OO: que al conocer lo bsico de OO automticamente vamos a
construir sistemas, flexibles, reutilizables y mantenibles.
Desarrollador: Y No es as?
Gur: No. Como veremos, construir sistemas OO que tengan estas
propiedades no es tan obvio y se descubren solamente con trabajo
duro.
Desarrollador: Pienso que ya lo entiendo. Estas maneras, a veces no
tan obvias, de construir sistemas OO han sido recolectadas
Gur: s, en un grupo de patrones llamados Patrones de Diseo.
Desarrollador: entonces, conociendo patrones, puedo saltarme el
trabajo duro e ir directamente a diseos que ya funcionan?
Gur: s, hasta cierto punto, pero recuerda, el diseo es un arte.
Siempre habrn un precios que pagar. Pero, si sigues patrones ya
comprobados, estars bastante adelantado.
Desarrollador: Qu puedo hacer si no encuentro un patrn?

Gur: Existen algunos principios de diseo que respaldan a los


patrones, y conociendo estas te ayudarn a replantear tu diseo
cuando no encuentres un patrn que solucione tu problema.
Desarrollador: Principios? Adems de Abstraccin,
encapsulamiento y
Gur: S, uno de los secretos de crear sistemas OO mantenibles es
pensar cmo pueden cambiar en el futuro y estos principios
solucionan estos problemas.
Recuerda, conocer conceptos
como abstraccin, herencia y
polimorfismo no te hace un
diseador orientado a
objetos. Un gur en diseo
piensa en como crear diseos
flexibles que sean fciles de
mantener y que puedan
evolucionar con los cambios

OO Bsico

n
Abstracci
miento
Encapsula
mo
Polimorfis
Herencia

OO
Principioslo que vara

r
re
Encapsula
osicin sob
p
m
o
c
r
ri
Prefe
no
herencia
a interfaz,
n
u
a
r
a
m
Progra
entacin
m
le
p
im
a
n
u

OO
itmos,
Patrones fine una familia de algorce
tegy de
, y los ha

S t ra
no de ellos
u
a
d
a
c
la
u
que los
ja
e
d
y
encaps
g
e
t
bles. Stra
ente de los
intercambia en independientem
var
algoritmos
utilizan
s
lo
e
u
q
s
cliente

Sumario
Conocer lo bsico de OO no te hace un buen diseador
OO
Los buenos diseos OO son reusables, extensibles y
mantenibles
Patrones te ensean a crear sistemas con buenas
cualidades de diseo OO
Patrones son Experiencias comprobadas OO
Patrones no te dan cdigo sino soluciones generales a
problemas de diseo

Sumario
No fueron inventados, fueron descubiertos
Patrones y principios administran el problema del
cambio en el software
Patrones permiten que partes de un sistema varen
independientemente de otras
Buscamos tomar lo que varia en un sistema y lo
encapsulamos
Patrones provee un lenguaje compartido

You might also like