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 09-10-2012
agustinbus agustinbus is offline
Miembro
 
Registrado: ago 2007
Posts: 44
Poder: 0
agustinbus Va por buen camino
Duda - Desarrollo OOP en capas

Buenas compañeros! como están? Abro este hilo debido a que quiero cambiar la forma de trabajar y hacerlo de una manera mas correcta.
Estuve buscando mucho y vi varios post en el foro y en otros lados pero ninguno me aclaró mucho.

Actualmente realizo mis trabajos de forma orientada a eventos y muy desordenada, y me gustaría comenzar a desarrollar aplicando la arquitectura en 3 capas, me refiero a Datos, Negocio y Presentación para poder separar la lógica del GUI. Ademas quiero comenzar a desarrollar librerias de clases, para utilizar en futuras aplicaciones, por ejemplo TClientes, TProveedores, TFacturas, TArticulos, etc.

Tengo varias dudas al respecto y se las menciono a continuación:

1- Es conveniente crear un Unit para cada clase, es decir crear un Unit para TClientes uno para TProveedores, etc.. y referenciarlos segun mi necesidad? o uno solo con todas las clases?

2- Para un alta por ejemplo de un cliente, quien seria el responsable de hacer el insert en la BBDD? La capa de datos? la de Negocio? El Unit TCliente con un metodo propio de la clase?

3- Cual es el rol de la capa de Negocio?


Tenia pensada otra forma de trabajar pero no se si esta bien, esta forma seria:

- Crear Units para cada clase por ejemplo TCliente
- Cada clase tendra sus datos privados (nombre, apellido, fecha nacimiento,etc...)
- Cada clase tendra sus propios metodos get y set para acceder a los datos privados.
- Cada clase tendra sus propios metodos para mantener la base de datos(es decir altas bajas modificaciones). Me refiero a crear un metodo insertar que guardara los datos en la base de datos por lo tanto cuando quiera guardar los datos del cliente hare:
Código Delphi [-]
cliente.Insertar(nombre,apellido,...);

y la definicion del metodo seria mas o menos asi:
Código Delphi [-]
cliente.Insertar(nombre,apellido,...);
begin
  QClientes.Close;
  QClientes.SQL.Clear; 
  QClientes.SQL.Add('INSERT INTO Clientes (NOMBRE, APELLIDO,...) values (:nom, :ape...)');
  QClientes.ParamByName('nom').Value := nombre;
  QClientes.ParamByName('ape').Value := apellido;
  QClientes.ExecSQL;
end;

Es correcto el razonamiento anterior? Un problema que encuentro es al momento de reutilizar la clase TCliente tendre que utilizar el mismo nombre para el TZQuery es decir QClientes.

Perdon por tantas preguntas, pero es un tema que no tengo muy claro.
Espero puedan ayudarme y desde ya muchas gracias a todos!!!
Responder Con Cita
  #2  
Antiguo 10-10-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por agustinbus Ver Mensaje
1- Es conveniente crear un Unit para cada clase, es decir crear un Unit para TClientes uno para TProveedores, etc.. y referenciarlos segun mi necesidad? o uno solo con todas las clases?
Depende de las necesidades y el diseño que tu consideres oportuno. Pero un primer criterio a considerar es el acoplamiento. Habrá situaciones que ameriten disponer varias clases en una misma unidad, y habrá otras en los que una clase por unidad.

Cita:
Empezado por agustinbus Ver Mensaje
2- Para un alta por ejemplo de un cliente, quien seria el responsable de hacer el insert en la BBDD? La capa de datos? la de Negocio? El Unit TCliente con un metodo propio de la clase?
Desde el pensamiento basado en el patrón Capas (Layers) y de los buenos principios quien asume la responsabilidad de materializar un objeto es la capa de persistencia.

Cita:
Empezado por agustinbus Ver Mensaje
3- Cual es el rol de la capa de Negocio?
Disponer en ésta las clases necesarias que dan forma justamente, al contexto del negocio. Es la extensión del concepto de Lógica. Toda potencial clase candidata y conceptual que se prevee dentro del contexto bajo estudio puede que sea de utilidad para dar forma al sistema.

Cita:
Empezado por agustinbus Ver Mensaje
Tenia pensada otra forma de trabajar pero no se si esta bien, esta forma seria:

- Crear Units para cada clase por ejemplo TCliente
Ya he dicho que es una cuestión de diseño y necesidades, y de un adecuado nivel de acoplamiento.
Una clase que no sabe delegar y comunicarse con otra no sirve. Como así también una clase altamente acoplada y relacionada a muchas tampoco sabe delegar. En el medio tienes la respuesta.

Cita:
Empezado por agustinbus Ver Mensaje
- Cada clase tendra sus datos privados (nombre, apellido, fecha nacimiento,etc...)
- Cada clase tendra sus propios metodos get y set para acceder a los datos privados.
Este... creo que es requisito indispensable para que se mantenga el concepto detrás del paradigma OO. Se da por entendido que es así

Cita:
Empezado por agustinbus Ver Mensaje
- Cada clase tendra sus propios metodos para mantener la base de datos(es decir altas bajas modificaciones). Me refiero a crear un metodo insertar que guardara los datos en la base de datos por lo tanto cuando quiera guardar los datos del cliente hare:
Código Delphi [-]
cliente.Insertar(nombre,apellido,...);

y la definicion del metodo seria mas o menos asi:
Código Delphi [-]
cliente.Insertar(nombre,apellido,...);
begin
  QClientes.Close;
  QClientes.SQL.Clear; 
  QClientes.SQL.Add('INSERT INTO Clientes (NOMBRE, APELLIDO,...) values (:nom, :ape...)');
  QClientes.ParamByName('nom').Value := nombre;
  QClientes.ParamByName('ape').Value := apellido;
  QClientes.ExecSQL;
end;


Es correcto el razonamiento anterior? Un problema que encuentro es al momento de reutilizar la clase TCliente tendre que utilizar el mismo nombre para el TZQuery es decir QClientes.
He dicho que formalmente la responsabilidad de material un objeto desde y hacia la base de datos pasa por una capa de persistencia.
No es un pecado hacer lo que sugieres, pero tu diseño tiene un problema de cohesión. Fíjate que ahora la clase no sólo asume la responsabilidades que se han previsto para su contexto sino que ahora debe hacerse cargo de las operaciones sobre la base de datos... Se está perdiendo cohesión. Y otro punto, como dices: acabas atando a tu clase a una tecnología puntual de acceso a base de datos.
Precisamente por esto es que se sugiere la presencia de una capa de persistencia.

Cita:
Empezado por agustinbus Ver Mensaje
Perdon por tantas preguntas, pero es un tema que no tengo muy claro.
Espero puedan ayudarme y desde ya muchas gracias a todos!!!
Existen en el mercado algunos frameworks de persistencia. Podrías examinarlos. Aunque yo primero te sugeriría que te familiarices más con el paradigma OO, los patrones de diseño y el A/DOO. Lectura casi obligada que te sacará más que unas cuantas dudas: UML y Patrones y una Introducción al Análisis y Diseño Orientado a Objetos y al Proceso Unificado de Craig Larman.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #3  
Antiguo 10-10-2012
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 21
gatosoft Va camino a la fama
Bueno, además de la lectura obligada que recomienda Delphius, es necesario poner en práctica los conceptos aprendidos, que pueden llegar a ser muy abstractos cuando ya se tiene un paradigma de programación en la cabeza...

Cita:
Empezado por agustinbus Ver Mensaje
1- Es conveniente crear un Unit para cada clase, es decir crear un Unit para TClientes uno para TProveedores, etc.. y referenciarlos segun mi necesidad? o uno solo con todas las clases?
Creo que tu mismo te repondes: "Es conveniente...según mi necesidad" (al igual que reponde Delphius "Depende de tus necesidades")

En mi poca experiencia personal sobre el tema, DEFINITIVAMENTE SI te recomiendo trabajar una unidad por cada clase, aunque lógicamente habrán ocasiones en que sea necesario definir mas de una clase en la misma unidad. (Generalmente cuando estan muy relacionadas).

A manera de ejercicio recomiendo siempre pensar que cada clase se diseña para ser publicada y comercializada de forma separada, como si estuvieras diseñando un componente. El objetivo de esto es llegar a un nivel alto de abstracción e independencia de cada clase.

Hago un paréntesis para comentar un detalle en la forma como nombras las clases, aunque no es importante, (y además depende de tus necesidades), tus clase no deberían llamarse TClientes, TProveedores, TFacturas... sino TCliente, TProveedor, TFactura... sencillamente por que eso te lleva a un nivel mas de abstracción. (individual vs. colectivo). No es lo mismo decir LosClientes.Crear, LosClientes.Guardar, que ElCliente.Cargar y ElCliente.Guardar. La lógica y el procesamiento en cada caso es distinto. Aunque vuelvo y repito depdne de lo que estes trabajando.

Cita:
Empezado por agustinbus Ver Mensaje
2- Para un alta por ejemplo de un cliente, quien seria el responsable de hacer el insert en la BBDD? La capa de datos? la de Negocio? El Unit TCliente con un metodo propio de la clase?
Necesariamente la capa de datos... en el momento que comiences a definir sentencias SQL en la capa de negocio estas reduciendo el modelo a dos capas... En general cada capa debe ser lo mas sencilla posible, al punto que las primeras capas sean como lenguaje natural... (Cliente.Guardar y la capa de Datos o de persistencia sabrá como se las arregla para almacenar dicha información.

Esto es importante ya que si logras independizar la capa de datos de las otras dos, podras pensar en un sistema multiBD o en un sistema que trabaje igual Local que de forma remota.

Cita:
Empezado por agustinbus Ver Mensaje
3- Cual es el rol de la capa de Negocio?
La capa de negocio se debe concentrar en recoger los datos (De la GUI, De un archivo, de la capa de persistencia), procesarlos, validarlos (de acuerdo a unas reglas de negocio) y enviarlos de nuevo a la Capa de presentación o a la de persisntecia según corresponda.

Piensa que el dia de mañana ya no vas a trabajar tu sistema en un PC con interfaz Windows, sino que vas a exponer tu aplicación como servicios web... Tu lógica de negocio o deberia cambiar, ni tampoco tu capa de persistencia...

estaria mal encontrar en tu capa de negocio algo como:
Código Delphi [-]
Procedure SetNombreCliente;
Begin
  Nombre:= Form1.Edit1.text;
end;

Por que estarias amarrando tu clase a la forma que estas trabajando.... Además como regla, "las capas internas no deben utilizar (Uses) las capas externas"...

Presentación ==Utiliza==> Negocio ==Utiliza==> Persistencia

Cita:
Empezado por agustinbus Ver Mensaje
Tenia pensada otra forma de trabajar pero no se si esta bien, esta forma seria:

- Crear Units para cada clase por ejemplo TCliente
- Cada clase tendra sus datos privados (nombre, apellido, fecha nacimiento,etc...)
- Cada clase tendra sus propios metodos get y set para acceder a los datos privados.
No hay discusión, es regla por la filosofía de objetos

Cita:
Empezado por agustinbus Ver Mensaje
- Cada clase tendra sus propios metodos para mantener la base de datos(es decir altas bajas modificaciones). Me refiero a crear un metodo insertar que guardara los datos en la base de datos por lo tanto cuando quiera guardar los datos del cliente hare:
Código Delphi [-]
cliente.Insertar(nombre,apellido,...);

y la definicion del metodo seria mas o menos asi:
Código Delphi [-]
cliente.Insertar(nombre,apellido,...);
begin
  QClientes.Close;
  QClientes.SQL.Clear; 
  QClientes.SQL.Add('INSERT INTO Clientes (NOMBRE, APELLIDO,...) values (:nom, :ape...)');
  QClientes.ParamByName('nom').Value := nombre;
  QClientes.ParamByName('ape').Value := apellido;
  QClientes.ExecSQL;
end;

Es correcto el razonamiento anterior? Un problema que encuentro es al momento de reutilizar la clase TCliente tendre que utilizar el mismo nombre para el TZQuery es decir QClientes.
Aquí en cambio si discuto.... como te comentaba anteriormente, es recoemndable (No es verdad absoluta) mantener alejado de la capa de negocio los componentes especificos de base de datos, o algo que amarre a la clase a un motor exclusivo...

Por otro lado, te sugeriria que manejaras otra filosofia en cuanto a la forma como ves la clase clientes... Clientes.Insertar(parametros)... está muy ligado a pensar en base de datos.... debes pensar mas en tu negocio y en lo que representa para ti un cliente... Es decir, deberias trabajar algo como:

Código Delphi [-]
cliente.Nuevo; //inicializa las variables
cliente.Nombre:= 'Perico';
Cliente.Apellido:= 'De los Palotes';
Cliente.Validar;


if Cliente.EstaOK then
   cliente.Guardar
else
   cliente.GenerarError('Error'); //Lo alamcena para ser presentado en la GUI según convenga...
                                  // o simplemente geners el raise... 


Cliente.Cargar(CodigoDeCliente);
Cliente.CalcularSaldos;


Separar en capas y trabajar clases independientes (tipo componente) puede representar un trabajo dispendioso... para algunos innecesario o redundante, pero tiene muchas ventajas a la hora de moverte entre arquitecturas..

En mi experiencia reciente, tuve la oportunidad de comprobar sus beneficios....

Yo tenia una aplciación Cliente servidor que utilizaba una clase TComprobanteContable. esta clase a su vez utilizaba una clase TEjecutorSQL que se encargaba de hacer el "trabajo sucio" en la base de datos... entonces mi clase funcionaba algo asi:

Código Delphi [-]
Function TComprobanteContable.Guardar: Boolean;
Begin
  if Self.ValidarDatos then
     if EjecutorSQL.Ejecutar('GuardarComprobantes', '<%ListaParametros%>') then
        Result:= True
     else
        Result:= False;  
end;

Mi ejecutorSQL es un componente que previamente he conectado a una base de datos (PostgreSQL, Interbase, Oracle o SQL server)... ¿como lo hace? pues a mi clase TComprobanteContable no le importa... solo le importa que cumpla con su parte...

Bueno, siguiendo con la historia... cuando quise migrar a la nube mi aplicación con DataSnap, pues no tuve que cambiar mi GUI, ni mi TComprobanteContable, ni mi ejecutor... solo tuve que crear unas clases TComprobanteContableRemoto, TEjecutorSQLRemoto que utilizaban los Mismos Metodos de las clases definidas inicialmente, es decir algo como:

Código Delphi [-]
Function TComprobanteContableRemoto.Guardar: Boolean;
Begin
  Result:= ClientModule1.ServerMethodsComprobanteClient.Guardar;
end;



Espero haber sido claro y haberte ayudado en algo...
Responder Con Cita
  #4  
Antiguo 10-10-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Impresionante Gatosoft,
Que bien has ampliado mis palabras. Con eso creería que casi todas las dudas ya se disiparían.

Yo quisiera aclarar que al momento de leer el libro que recomendé no se lo hiciera de una sola pasada. Yo estimo que mínimo se lo va leer unas 10 veces. Hay que hacer una pequeña observación sobre dicho material bibliográfico: se asume que hay una preparación previa sobre los conceptos de POO y algo de UML. No está pensado para enseñar POO pero si está muy enfocado para aportar una perspectiva muy analista sobre dicho paradigma. Su aporte al A/DOO es riquísimo.

Para UML, que recontra recomiendo su uso, lo más confiable y completo es leer UML 1.5 (mínimo... en lo posible 2.0 y si desean pueden ir a 2.2; la 2.5 todavía está en borrador que yo sepa). Léase el libro de los 3 gurus; que es el más en detalle y completo ¡y oficial!. Otro de los muy citados es UML Distilled Recuerdo que en otro hilo se ha aportado biografía sobre el tema.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #5  
Antiguo 12-10-2012
agustinbus agustinbus is offline
Miembro
 
Registrado: ago 2007
Posts: 44
Poder: 0
agustinbus Va por buen camino
Muchas gracias por responder Delphius y gatosoft, de verdad me sirvieron de mucho las explicaciones que me dieron. De verdad valoro su dedicacion para responder de forma tan completa y clara. Da gusto discutir estos temas con gente que sabe. Lo unico que me hace falta es comenzar con practica. UML y patrones lo lei ya dos veces y conozco de patrones pero nunca supe llevarlos a la practica. Nuevamente gracias!
Responder Con Cita
  #6  
Antiguo 13-10-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por agustinbus Ver Mensaje
Muchas gracias por responder Delphius y gatosoft, de verdad me sirvieron de mucho las explicaciones que me dieron. De verdad valoro su dedicacion para responder de forma tan completa y clara. Da gusto discutir estos temas con gente que sabe. Lo unico que me hace falta es comenzar con practica. UML y patrones lo lei ya dos veces y conozco de patrones pero nunca supe llevarlos a la practica. Nuevamente gracias!
No es tan sencillo abordar una práctica sobre los patrones... sobre todo si no se le ha leído con mucha profundidad. ¿Porqué crees que sugerí la lectura del libro en no menos de 10 veces? Para alguien que apenas se introduce en OO pensar en patrones le rompe los esquemas. Porque te hace unos giros conceptuales de la forma en como uno piensa en objetos. Ya no se trata del típico ejemplo de TPerro y TAnimal... aunque bien se podría usar esos ejemplos simples para exponer el tema.

Para abordar los patrones se requiere además del complemento del UML por lo que es necesario tener las nociones básicas de ésto.
Las cosas se te van a ir forjando en la medida en que lo vayas volcando en la práctica. Nadie dijo que sea fácil.

Como consejo final: ¡tampoco hay que dejarse contagiar de la patronitis! Craig en su libro le dedica unas palabras a esa enfermedad y quien escribe estas líneas también te lo advierte ¡por experiencia propia!

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #7  
Antiguo 15-10-2012
ASAPLTDA ASAPLTDA is offline
Miembro
 
Registrado: jun 2003
Ubicación: COLOMBIA-CALI
Posts: 639
Poder: 21
ASAPLTDA Va por buen camino
Smile DataSnap

Hola Gatosoft

Cuando leemos estas disertaciones uno respira profundo para tratar de entender, sobre todo aquellos que no tenemos formacion en informatica, si no que solo aprendimos a programar hace ya varios anos.

He querido utilizar DataSnap , sobre todo la parte de los callback , es posible que nos hablas sobre tu experiencia con datasnap ?
Responder Con Cita
  #8  
Antiguo 16-10-2012
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 21
gatosoft Va camino a la fama
Amigo ASAPLTDA, la verdad mi experiencia con DataSnap es bastante reciente, y todo gracias a que me vi obligado a estudiar sobre el tema debido a un proyecto nuevo que estoy trabajando para la empresa que acabé de formar...

En lo que si considero que tengo bastante experiencia es en POO, y creo que eso me ha facilitado comprender y adaptarme al concepto de DataSnap... Aunque uno nunca termina de aprender y siempre que me paso por el club para ver las respuestas de los verdaderos "maestros" que frecuentan este sitio, encuentro cosas que me aún me sorprenden de Delphi

Pues como decía, en estos meses de lucha he aprendido bastante y precisamente estoy preparando un blog o videoblog para exponer lo poco que conozco sobre ciertos temas. Creo que después de tantos años...ya es hora...!

De cualquier forma estoy atento a cualquier información que quieras sobre el tema... es mas si me paso por cali en estas vacaciones podríamos vernos y hablar de negocios (de empresa a empresa)...

Por ahora, si aún no te has pasado por ahí, te recomiendo y les recomiendo a todos la serie de videos Delphi Labs, de Pawel Glowacki, Son muy buenos para iniciarse en DataSanap.

Un saludo
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
desarrollo WEB vs. desarrollo tradicional _iceman Debates 42 28-02-2013 17:36:00
Duda sobre OOP y capas AzidRain OOP 4 04-08-2007 00:25:35
aplicacion 3 capas en c# cuscus .NET 2 15-11-2005 21:06:57
Clipper en 3 Capas ???? AGAG4 Providers 3 30-06-2005 19:03:17
Dibujando en capas blueicaro Gráficos 1 26-04-2005 09:46:02


La franja horaria es GMT +2. Ahora son las 20:27:48.


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