El código salvaje crece de una manera incontrolada, esto
hace que en muchos casos se pierda el control del mismo, y en casos extremos se
tengan que hacer completos proyectos que si bien en su fase de diseño fueron
muy buenos, con una arquitectura estable, conforme se van agregando nuevas
funcionalidades y más desarrolladores modifican el código, estos se convierten
en verdaderos monstros de Frankenstein.
Muchas piezas de código operando para crear nuevas
funcionalidades, y en ciertas ocasiones por no conocer el sistema, estas hacen
que el sistema sea inestable.
El tiempo de desarrollo se incrementa, la calidad baja, y de
la misma forma baja la satisfacción del cliente.
Pero, ¿Hay alguna forma de modificar funcionalidad que sea
no tan dolorosa?
Vamos a platicar de un patrón de diseño que es para esto, su
nombre es Decorator, y se emplea para añadir de manera dinámica funcionalidad a
un objeto, de esta forma podemos incrementar las características del objeto,
sin que esto nos represente un cambio doloroso.
Eso si hay que cambiar un poco nuestra mentalidad para
usarlo, y pensar más en términos del patrón
Su principal característica, es que nos permite agregar de
manera incremental responsabilidades, el patrón lo aplicamos como si fueran
capas y las capas nos brindan nuevas características, imaginemos que es una
perla que se está creando y cada capa es una aplicación del patrón.
Este es un patrón estructural y lo podemos usar durante el
diseño, mantenimiento o extensión de funcionalidad.
Podemos representar el patrón de la siguiente forma
Sin embargo creo que esto lo podemos ilustrar mejor con un
poco de código.
Imaginemos esto somos una fábrica de carros, y vamos y vamos
a ponerle el radio a uno de nuestros carros, así que crearemos una interfaz en
la cual se encontrara el método encender radio
namespace decorator01
{
public interface ICarro
{
void EncenderRadio();
}
}
El radio lo vamos a implementar en nuestro modelo básico
public class CarroEstandar : ICarro
{
public void EncenderRadio()
{
Console.WriteLine("Radio FM -
Mono");
}
}
Como se puede ver el modelo básico cuenta con un Radio FM
con sonido mono aural, bueno viene un nuevo modelo, en el cual se requieren
mejoras a este radio, así que tomamos el modelo básico y lo mejoramos
public class CarroMejorado : ICarro
{
ICarro CarroBase;
public CarroMejorado (ICarro I)
{
CarroBase = I;
}
public void EncenderRadio()
{
CarroBase.EncenderRadio();
Console.WriteLine("Radio
Satelital");
}
}
Ahora el radio cuenta con una nueva función, sin perder la
primera, si tuviéramos otro modelo, podemos crearlo ahora partiendo de
cualquiera de los modelos anteriores.
public class CarroBlindado : ICarro
{
ICarro CarroBase;
public Boolean DobleBlindado { get; set; }
public CarroBlindado(ICarro I)
{
CarroBase = I;
}
public void EncenderRadio()
{
CarroBase.EncenderRadio();
{
Console.WriteLine("Audio Alta calidad");
}
else
{
Console.WriteLine("Audio
Especial");
}
}
}
Construyamos ahora nuestros carros:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Construyendo
carro estandar");
CarroEstandar cr1 = new CarroEstandar();
cr1.EncenderRadio();
Console.WriteLine("Construyendo
carro Mejorado");
CarroMejorado cr2 = new CarroMejorado(cr1);
cr2.EncenderRadio();
Console.WriteLine("Construyendo
carro blindado");
CarroBlindado cr3 = new CarroBlindado(cr2);
cr3.DobleBlindado = true;
cr3.EncenderRadio();
Console.ReadLine();
}
Al iniciar la producción vemos lo siguiente
Como podemos observar se puede agregar funcionalidad de
manera dinámica de una forma mucho más libre que empleando la herencia
Di no al código salvaje