jueves, 25 de septiembre de 2008

PATRONES ESTRUCTURALES (I). Patrón Adapter

El patrón Adapter proporciona un interface de una clase para otra que en circunstacias normales
sería incompatible. El adaptador convierte llamadas a su propio interface en llamadas al interface
original, por lo que se reduce la cantidad y complejidad del código para realizar la adaptación.
Este patrón también recibe el nombre de Wrapper (traducido al español envoltorio).

Dentro del patrón Adapter se pueden diferenciar dos casos:

  • El objeto Adapter. En este caso, lo que utiliza es una relación de asociación entre el Adaptador y el objeto adaptado.
  • La clase Adapter. La clase Adapter utiliza la herencia múltiple existente en algunos lenguajes como C++ o python o una herencia simple con una implementación de un interfaz como se realizaría en Java.
A continuación, os presento un ejemplo de la clase Adapter. Este ejemplo está basado en el funcionamiento del comando tar utilizado ampliamente en el mundo *NIX. Por defecto, este comando crea un fichero que contiene todos los archivos especificados en su entrada en la unidad de cinta predeterminada del sistema. Funcionaría de forma similar a los programas "zip" existentes pero sin comprimir, algo así como un fichero iso.

La característica que queremos remarcar aquí, es que por defecto el archivo se escribe en la unidad de cinta en vez de en el disco como es habitual en nuestros días. En principio podríamos pensar que un dispositivo de cinta es diferente de un dispositivo de disco por lo que crearemos una clase que adapte el interfaz existente para la unidad de cinta al funcionamiento de un interfaz de disco. Espero que el ejemplo sea lo suficientemente claro y que no se vea complicado por el ejemplo que se me ha ocurrido para ilustrarlo.



class Cinta(object):
def Escribir(self):
print "Escribiendo a cinta ..."
class Disco(object):
def EscribirADisco(self):
print "Escribiendo a disco ..."
class AdaptadorDiscoCinta(Cinta, Disco):
def Escribir(self):
self.EscribirADisco()

class MiTar(object):
handler = None
def __init__(self, param):
if param == "disco":
self.handler = AdaptadorDiscoCinta()
else:
self.handler = Cinta()
def backup(self):
self.handler.Escribir()

t = MiTar("")
t.backup()

t2 = MiTar("")
t2.backup()