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:
- 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.
- 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 del 21%, en el caso
de Luxemburgo
es variable (12% para los
servicios,
15% para el material). El cálculo del IVA
requiere dos operaciones de
cálculo 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
mé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