Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-11-2006
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
OOP y referencias circulares

Codificando un diagrama UML me paso algo raro con Delphi al tratar de hacer que las clases interactuen entre si ya me jaló.

La idea es para un catalogo de cuentas, la idea es la siguiente:

tengo la clase Catalogo que es diagamos el "corazon" de todo, a su vez esta clase contiene una clase TVentanaCat que es un TForm, y una clase TCuenta (TOBject). La interaccion de TCatalogo con TCuenta no tiene problema ya que TCatalogo se encarga de crear, manipular y destruir a TCuenta sin problema.

Ahora bien, TVentanaCat, es la parte "visual" de TCatalogo, o sea la forma que muestra en forma grafica las cuenta con la que esta trabajando en ese momento. El problema es que como TVentanaCat es parte de TCatalogo, para usarla debo poner un uses en TCatalogo. Por su parte TVentanaCat le tiene que pasar a TCatalogo los mensajes de lo que el usuario haya solicitado para que lo ejecute (recordemos que TVentanaCat solo es el "cascaron", no sabe como manipular una TCuenta). Ahi es donde entra el problema, para poder accesar a TCatalogo tengo que añadir un uses pero como en TCatalogo a su vez referencía TVentanaCat se crea una referencia circular que no es posible compilar.

La solución puede ser que TCatalogo y TVentanaCat sean el mismo objeto, es decir, incluir todo el código para manipular TCuenta dentro de TVentanaCat...pero no me parece muy elegante.

Otra opción es hacer a la inversa, que TVentanaCat sea la clase de más alto nivel y que contenga a TCatalogo para manipularlo...pero tampoco se me hace muy elegante.

En Java si puede hacerse como lo estoy tratando sin problemas, pero no quiero usarlo porque swing no ofrece tanta calidad como las VCL y otros componentes que ya tengo de Delphi.

Siempre he diseñado usando programación mixta: procedural y OOP, pero ya me quiero "ordenar" y usar solo OOP.


Como me recomiendan hacer el diseño?
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #2  
Antiguo 24-11-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No sé yo si esto te pueda servir. La idea es que dos unidades pueden usarse una a la otra siempre y cuando no sea ambas en la parte de interface. En el ejemplo que te pongo factorizo por una tercera unidad común que ambas llaman desde su parte interface. Esta unidad común contiene interfaces a las clases, pero no implementan nada. Cada unidad Catalogos y Ventanas usan esta unidad común para poder declarar sus propiedades en la parte interface. Pero es en la parte implementation donde cada una llama a la otra para poder construir realmente el objeto que implementa la interfaz.

Código Delphi [-]
// Intf.pas

unit Intf;

interface

type
  IVentana = interface;

  ICatalogo = interface
    function GetVentana: IVentana;
  end;

  IVentana = interface
    function GetCatalogo: ICatalogo;
  end;

implementation

end.
-------------------------------------------------------------------------------

// Catalogos.pas

unit Catalogos;

interface

uses
  Intf;

type
  TCatalogo = class(TInterfacedObject, ICatalogo);
  private
    FVentana: IVentana;

  public
    function GetVentana: IVentana;
    constructor Create;
  end;

implementation

uses
  Ventanas;

function TCatalogo.GetVentana: IVentana;
begin
  Result := FVentana;
end;

constructor TCatalogo.Create;
begin
  FVentana := TVentana.Create;
end;

end.
-------------------------------------------------------------------------------

// Ventanas.pas

unit Ventanas;

interface

uses
  Intf;

type
  TVentana = class(TInterfacedObject, IVentana);
  private
    FCatalogo: ICatalogo;

  public
    function GetCatalogo: ICatalogo;
    constructor Create;
  end;

implementation

uses
  Catalogos;

function TVentana.GetCatalogo: ICatalogo;
begin
  Result := FCatalogo;
end;

constructor TVentana.Create;
begin
  FCatalogo := TCatalogo.Create;
end;

end.

Ahora, al margen de esto, pienso que es un poco raro que una clase, TCatalogo se encargue de su propia representación visual. De alguna manera esto la hace dependiente de la parte visual, cosa que no se recomienda. Quizá te convendría factorizar por un tercer objeto que se encargue de crear la ventana y pasarle los datos de un objeto TCatalogo.

// Saludos

Última edición por roman fecha: 24-11-2006 a las 00:58:01.
Responder Con Cita
  #3  
Antiguo 24-11-2006
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
Finalmente obté por algo muy parecido a lo que comentas al final...Le di a la ventana métodos para que pueda manipular el TCatalogo, es decir, mostrarlo, añadirle o quitarle cuentas, etc. pero de manera visual. Si cambio el catálogo no afecta a la ventana pues esta solo le manda mensajes tipo "Borracuenta(numCuenta)" o "ObtenCuentas". Lo hice así mas que nada porque la ventana en cuestion, tendrá algo de interactividad que requiere estar actualizando cosas a TCatalogo. El TCatalogo lo crea en este caso la aplicación principal y se lo pasa a la ventana para que lo manipule, una vez cerrada la ventana la aplicación lo destruye.

Mira que simple se vuelve el código cuando lo ve uno así, si lo hubiese hecho como antes me hubiera quedado un rollazo de n lineas, así como voy me quedan métodos pequeñitos de unas cuentas líneas y que decir de como se puede leer el código...

grax
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Operaciones basiscas listas doblemente enlazadas circulares fede7 Varios 16 07-04-2006 23:15:35
Referencias a componentes tica OOP 3 28-01-2004 15:07:09
Eliminar referencias tica Varios 2 09-12-2003 18:13:33
Consultas de referencias cruzadas Manuela Impresión 0 19-08-2003 21:50:43
Referencias circulares aparentes con SPs mlara Firebird e Interbase 6 06-07-2003 16:29:19


La franja horaria es GMT +2. Ahora son las 04:26:33.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi