Translate

viernes, 22 de junio de 2012

Clases colaborativas en Delphi. Parte II


En el artículo anterior revisabamos las formas de agregar nueva funcionalidad a una Clase, intentando mantener el codigo lo mas ordenado posible ..

En la practica esto es mas dificil de lo que parece y cualquier programador sabe que al cabo de algunas extensiones el codigo original, se transforma en una secuencia de codigo, dificil de leer y fundamentalmente dificil de extender o modificar.

Las tres formas explicadas anteriormente son:

La programacion lineal

Es simplemente escribir en un solo metodo todo la funcionalidad, lo que resulta naturalmente en un codigo absolutamente no reusable.

Pero la programacion lineal tiene en general una ventaja indudable .. es muy facil de leer !! .. porque el flujo procede de la primer linea a la ultima una despues de otra.

Este modo a pesar de ser tabu .. es de hecho utilizado por miles de programadores que simplemente no quieren tomarse la molestia de estructurar codigo.

La programacion estructurada

Simplemente, consiste en dividir un problema en partes e implementar cada parte en un nuevo metodo. De esta forma es posible identificar mejor las parte de un problema y eventualmente reusar aquellas que deban ser utlizadas en distintos contextos.

La programacion estructurada con sub rutinas

Similar a la anterior, pero las partes de un problema quedan estructuradas como sub rutinas de un metodo. En ese sentido, el metodo incluye todos los recursos necesarios para su implementacion: subrutinas, sub subrutinas (etc),
variables locales, sobrecarga .. y hasta recursividad ! (ver Clases Colaborativas Parte I)

Las clases colaborativas

Este enfoque no tiene nada de 'nuevo' .. tan solo que es muy poco usado. Consiste en la creacion de clases que se dedican a resolver problemas especificos. A la clase asi dedicada, no le 'importa' nada mas que el problema que tiene que resolver.

Todo el espacio de esta clase, esta precisamente dedicado a resolver el problema, incluyendo sus metodos y variables de instancia.

Si dos problemas se parecen, las soluciones pueden derivarse de clases colaborativas basicas o abstractas, que sientan las base de resolucion de un problema, en general.

La implementacion de estas clases, es sorprendetemente simple y promueve la resolucion ordenada de problemas o aspectos de una clase superior.

Por ejemplo:

TClase = class
public
   procedure ProblemaUno;  
end;

TClaseColaborativa = class;
TTipoDeClaseColaborativa = class of TClaseColaborativa;

TClaseColaborativa = class
private
    oClase: TClase;
protected
   procedure Inicio; virtual;
   procedure Proceso; virtual;
   procedure Fin; virtual;
   class function TipoDeClase: TTipoDeClaseColaborativa; virtual; abstract;    
public
   constructor Create(const oClasePar: TClase);
   procedure Resuelve; overload;
   class procedure Resuelve(const oClasePar: TClase);  overload;
end;

TResuelveProblemaUno = class(TClaseColaborativa )
protected
    class function TipoDeClase: TTipoDeClaseColaborativa;  override; 
end;

TResuelveProblemaDos = class(TClaseColaborativa)
protected
    class function TipoDeClase: TTipoDeClaseColaborativa; override;  
end;

implementation

{ TClase }

TClase.ProblemaUno;
begin
   TResuelveProblemaUno.Resuelve(Self);
end;

{ TClaseColaborativa }

TClaseColaborativa.Create(const oClasePar: TClase)
begin
   inherited Create;
  oClase:=oClasePar;
end;

TClaseColaborativa.Resuelve(const oClasePar: TClase);
begin
   with TipoDeClase.Create(oClasePar) do
  try
     Resuelve;
  finally
     Free;
  end;
end;

TClaseColaborativa.Resuelve;
begin
   Inicio;
   try
      Proceso;
   finally
      Fin;
   end;
end;

TClaseColaborativa.Inicio;
begin
end;

TClaseColaborativa.Proceso;
begin
end;

TClaseColaborativa.Fin;
begin
end;

{ TResuelveProblemaUno }

TResuelveProblemaUno.TipoDeClase; override;
begin
   Result:=TResuelveProblemaUno;
end;

{ TResuelveProblemaDos }

TResuelveProblemaDos.TipoDeClase; override;
begin
   Result:=TResuelveProblemaDos;
end;

Lo importante aqui son dos cosas ...

   TClase.ProblemaUno;
   begin
      TResuelveProblemaUno.Resuelve(Self);
   end;

La implementacion del ProblemaUno .. queda a cargo de la clase dedicada que es TResuelveProblemaUno, a traves del metodo de clase Resuelve. Y ademas .. 

   TClaseColaborativa = class
   .
   .
   end;

Esta es un clase basica que presta el marco general para las clases resolvedoras de problemas especificos que seran heredadas de esta misma.

No hay comentarios:

Publicar un comentario