Ver Mensaje Individual
  #9  
Antiguo 26-12-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Reputación: 25
Delphius Va camino a la fama
Hola NickName,
De curiosidad he vuelto para ver si respondías.

Me alegro que tengas en cuenta mis comentarios y que estés abierto a alternativas. No tengo Delphi a mano... pero al ver la forma en que tu haz hecho tu diseño, no lo veo correcto.

A mi modo de ver... no tiene sentido lógico que las clases Proveedor, Movimiento, etc hereden de Conexion.

Veamos si me explico: la asignación de responsabilidades es un juego sencillo. Al igual que en la realidad a uno le toca a hacer lo que sabe haber. Y claro está, si lo saber hacer es porque tiene la información para saber hacer su tarea. En POO esto se traduce: un objeto hace algo con la información que este tiene.
Un objeto que no sabe delimitar sus funciones y/o delegar parte de su trabajo a otro objeto tiene problemas de diseño. Y es aqui parte del problema. Una clase Movimiento debería delegar parte de su trabajo hacia la clase LineaMovimiento. Es como querer asignarle todo el trabajo de oficina a una persona.

Parte del problema se soluciona teniendo un ObjectList como te comentaba:

Código Delphi [-]
TMovimiento = class
  private
    FLineasMovimiento = TObjectList;
    { FLineasMovimiento es un contenedor. Contendrá todos los objetos
      de tipo TLineaDeMovimiento.
      Con esto se consigue que un Movimiento conozca sus respectivos
      detalles }
  public
     //...
  end;

Ahora continuando con el planteo. ¿Quien se encargaría de crear cada detalle del movimiento? O dicho de otro modo: ¿Que clase tiene la información necesaria para crear cada LineaMovimiento? Comprendiendo el modelo ("Un Movimiento está compuesto por al menos una Linea de detalle") podemos afirmar que la clase Movimiento es una excelente candidata.
Por lo que dicha clase debe contar con un método que realize esta operación. Por ejemplo:

Código Delphi [-]
procecure TMovimiento.CrearLineaMovimiento(...);
// Posiblemente sea aqui donde se pasan algunos valores iniciales
var Linea: TLineaDeMovimiento;
begin
  Linea := TLineaDeMovimiento.Create;
  //...
end;

¿Terminamos? No... Bueno... ya se ha conseguido hacer parte de la referencia... Hemos creado una linea, pero claro... aqui no termina la historia. ¿Cómo mantenemos la referencia? ¡FLineaMovimiento al rescate!

Una vez que se crea la linea de movimiento (y muy posiblemente se asignan algunos valores a sus propiedades), es necesaria asociarla al ObjectList... Podríamos hacer algo como:

Código Delphi [-]
procedure TMovimiento.AsociarLineaDeMovimiento(Linea: TLineaDeMovimiento);
begin
  FLineasMovimiento.Add(Linea);
  // No recuerdo bien que parámetros se necesitan...
end;

Y asi podemos continuar viendo que debe hacer cada clase y/o conocer cada clase.

Ahora pensemos... ¿Sería correcto que todas la clases entiendan de SQL y sepan conectarse a la base de datos? ¿Que tienen que ver un Movimiento, un Proveedor, una LineaDeMovimiento con el acceso a base de datos? Poco y nada. Ahora tu me dirás: ¿Pero que no es que cada clase debe hacer lo que sabe y cuenta con la información para ello? ¿Pero si cada una cuenta con la información necesaria porqué no hacer que ellas sean quienes accedan a la base de datos?

La respuesta es que la verdad está a medias. Es correcto el hecho de que tanto Proveedor, como Movimientos, etc... tienen la información necesaria. Pero ¿es necesario que todas sepan y entiendan de SQL? La respuesta es NO.
Lo correcto sería tener otra clase que sepa de SQL, entienda sobre base de datos.

Viendo que me aportaste mayor información acerca de tu dominio. Yo ya optaría por algo más modular. Me hablas de Ticket y su respectivo detalle.
Ya tienes 5 clases que aprenden SQL... contra una que entiende.

Tu viniste haciendo una asignación de responsabilidades a la inversa. Hiciste el trabajo sucio en la parte alta de la rama del diagrama y debería ir en la parte baja.

Lo más correcto sería que Proveedor, y demás se comuniquen con esta clase extraña que entiende de base de datos y nada más que de base de datos y le pasan los datos lo que se desea grabar, modificar, etc.

Por ejemplo tal vez algo como esto:

Código Delphi [-]
procedure TMovimiento.Registrar(Movimiento: TMovimiento);
begin
  AccesoDB.Grabar(Self);
end;

AccesoDB, podría leer desde las propiedades del Movimiento y en base a lo que lee arma un SQL y lo manda a ejecutar.

Lo más correcto es que no haya una única clase que se encargue del trabajo sucio. Es de esperar que sean varios objetos quienes colaboran en dicha tarea.

Yo ya te he comentado que si te impongo un modelo y mi punto de vista sería perjudicial para ti. Haz el tuyo y de alli estructura las clases correctamente.
En vista a que no tienes un diseño preliminar recomiendo que antes de seguir metiendo código te documentes mejor sobre UML.
No conduzcas por la carretera de POO sino tienes un mapa que te indique si vas bien o mal.

Podríamos continuar con las explicaciones, pero es un tema que no se aprende en pocos días. si bien aqui puede que haya espacio para ir redactando cada tema o duda que te vayan surgiendo... no va alcanzar para evacuarte todas tus dudas.
Lee UML y Patrones y asimilarás la idea y la filosofía que encierra el mundo POO.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]

Última edición por Delphius fecha: 26-12-2007 a las 21:11:07.
Responder Con Cita