miércoles, 4 de mayo de 2016

Template Method

DESCRIPCIÓN
El patrón de diseño Template Method forma parte de la familia de patrones denominados de comportamiento. Este tipo patrones ayudan a resolver problemas de interacción entre clases y objetos. Template Method nace de la necesidad de extender determinados comportamientos dentro de un mismo algoritmo por parte de diferentes entidades. Es decir, diferentes entidades tienen un comportamiento similar pero que difiere en determinados aspectos puntuales en función de la entidad concreta.

SOLUCIÓN INCORRECTA:
Una posible solución podría ser copiar el algoritmo en cada de las diferentes entidades cambiando la parte concreta en la que difieren. Esta solución tiene una consecuencia negativa ya que se genera código duplicado.

SOLUCIÓN CORRECTA:
La solución que propone el patrón Template Method es abstraer todo el comportamiento que comparten las entidades en una clase (abstracta) de la que, posteriormente, extenderán dichas entidades. Esta superclase definirá un método que contendrá el esqueleto de ese algoritmo común (método plantilla o template method) y delegará determinada responsabilidad en las clases hijas, mediante uno o varios métodos abstractos que deberán implementar.

REPRESENTACIÓN EN UML:

Como puede verse en el anterior diagrama, la superclase contiene el método plantilla, ese método con el algoritmo que comparten las entidades concretas (subclases). Como se puede apreciar, define una o varias operaciones concretas en forma de métodos abstractos que son usados por el método plantilla y que deben ser implementadas por las clases hijas. Dichos métodos abstractos representan los comportamientos concretos de las entidades.

DOMINIOS DE LA APLICACIÓN

El patrón se utiliza en los casos siguientes:
  1.      Una clase compartida con otra u otras clases con código idéntico que puede factorizarse siempre que las partes específicas a cada clase hayan sido desplazadas a nuevos métodos.
  2.     Un algoritmo posee una parte invariable y partes específicas a distintos tipos de objetos.

Ejemplo

En el sistema de venta online de vehículos, queremos gestionar pedidos de clientes de España y de Luxemburgo. La diferencia entre ambas peticiones concierne principalmente al cálculo del IVA. Si bien en España la tasa de IVA es siempre fija de21%, en el caso de Luxemburgo es variable (12% para los servicios, 15% para el material). El cálculo del IVA requiere dos operaciones delculo distintas en función del país.

Una primera solución consiste en implementar dos clases distintas sin súperclase común: PedidoEspaña y PedidoLuxemburgo. Esta solución presenta el inconveniente

importante de que tiene código idéntico que no ha sido factorizado, como por ejemplo la visualización de la información del pedido (método visualiza).

Podría incluirse una clase abstracta Pedido para factorizar los métodos comunes, como el método visualiza.

El patrón Template Method permite ir más lejos proponiendo factorizar el código común en el interior de los métodos. Tomemos el ejemplo del método calculaImporteConIVA cuyo algoritmo es el siguiente para España (escrito en pseudo- código).

calculaImporteConIVA:
importeIVA = importeSinIVA * 0,21;
importeConIVA = importeSinIVA + importeIVA;

El algoritmo para Luxemburgo tiene el siguiente pseudo-código.

calculaImporteConIVA:
importeIVA = (importeServiciosSinIVA * 0,12) + (importeMaterialSinIVA * 0,15);
importeConIVA = importeSinIVA + importeIVA;

Vemos en este ejemplo que la última línea del método es común a ambos países (en este ejemplo, sólo hay una línea común aunque en un caso real la parte común puede ser mucho más importante).

Reemplazamos la primera línea por una llamada a un nuevo método llamado calculaIVA. De este modo el método calculaImporteConIVA se describe en adelante de la siguiente forma:

calculaImporteConIVA:
calculaIVA();
importeConIVA = importeSinIVA + importeIVA;

El método calculaImporteConIVA puede ahora factorizarse. El código específico ha sido desplazado en el todo calculaIVA, cuya implementación es específica para cada país. El método calculaIVA se incluye en la clase Pedido como método abstracto.

El método calculaImporteConIVA se llama un método "modelo" (template method). Un método "modelo" incluye la parte común de un algoritmo que está complementado por partes específicas.

Esta solución se ilustra en el diagrama de clases de la figura 27.1 donde, por motivos de simplicidad, el cálculo del IVA de Luxemburgo se ha configurado con una tasa única
del 15%.

SOLUCIÓN EN JAVA
Descargue solución aquí

La clase abstracta Pedido incluye el método "modelo" calculaImporteConIVA que invoca al método abstracto calculaIVA.

La subclase concreta PedidoEspaña implementa el método calculaIVA con la tasa de
IVA español.


La subclase concreta PedidoLuxemburgo implementa el método calculaIVA con la tasa de IVA luxemburgués.


Por último, la clase TemplateMethod contiene el programa principal. Éste crea un pedido español, fija el importe sin IVA, calcula el importe con IVA y a continuación muestra el pedido. A continuación, el programa principal realiza la misma operación con un pedido luxemburgués.

0 comentarios:

Publicar un comentario