Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-02-2014
pape19 pape19 is offline
Miembro
 
Registrado: jul 2010
Posts: 96
Poder: 14
pape19 Va por buen camino
Programación Orientada a Objetos - Aplicación

Buenas tardes.

A algunos mi consulta les parecerá algo tonta, pero es algo que me está costando implementar en Delphi y necesito de su ayuda.

Las aplicaciones que he hecho en Delphi, sean simples o con alguna complejidad fue siempre programando de manera procedural, nunca cree una clase; y ahora necesito y siento curiosidad por aplicar todos mis conocimientos teóricos aprendidos de POO en la práctica, y tengo ciertas dudas del orden en el que se escriben las cosas.

Vamos a suponer, que mi aplicación es un ABM de Empleados, con una base de datos Firebird. Para conexion con la bd utilizo componentes IB. Creo la siguiente clase:

Código Delphi [-]
TEmpleado = class
    Referencia: Integer;
    Nombre: String;
    FechaNacimiento: TDate;
    Procedure ValidarEmpleado(objEmpleado : TEmpleado);
    Procedure GuardarEmpleado(objEmpleado : TEmpleado);

  private
    { Private declarations }
  public
    { Public declarations }
    Procedure SetReferencia(IdEmpleado: Integer);
    Procedure SetNombre(Nombre: String);
    Procedure SetFechaNacimiento(FechaNacimiento: TDate);
    Function GetReferencia(): Integer;
    Function GetNombre(): String;
    Function GetFechaNacimiento(): TDate;

Luego tengo un form(F_Empleados) con tres botones(alta, baja y modificación de empleados) y un DataModule(Name dmDatos) con un objeto IBTable, llamado tblEmpleados. El boton Alta:

Código Delphi [-]
procedure TF_Empleados.btnAltaClick(Sender: TObject);
begin
    Empleado := TEmpleado.Create();
    TblEmpleados.Active := True;
    TblEmpleados.Insert;
    F_ABMEmpleado.show;
end;

F_ABMEmpleado es otro form, el cual muestro al apretar Alta, donde tengo 3 Edits para el ingreso de los datos del empleado. Y un botón Guardar.

En ese botón guardar hago...

Código Delphi [-]
    Empleado.SetReferencia(Edit1.Text);
    Empleado.SetNombre(Edit2.Text);
    Empleado.SetFechaNacimiento(Edit3.Text);
    Empleado.ValidarEmpleado(Empleado);
    Empleado.GuardarEmpleado(Empleado);
    F_ABMEmpleado.Close;

Ahora les muestro mis métodos ValidarEmpleado() y GuardarEmpleado() de la clase Empleado

Código Delphi [-]
Procedure TEmpleado.ValidarEmpleado(objEmpleado : TEmpleado);
Begin
  if ((objEMpleado.Nombre = '') then
  Begin
    showmessage('ERROR');
    abort;
  End;
End;

Procedure TEmpleado.GuardarEmpleado(objEmpleado : TEmpleado);
Begin
    dmDatos.tblEmpleadosREFERENCIA.Value := objEmpleado.Referencia;
    dmDatos.tblEmpleadosNOMBRE.Value := objEmpleado.Nombre;
    dmDatos.tblEmpleadosFECHA_NAC.Value := objEmpleado.FechaNacimiento;

    dmDatos.tblEmpleados.Post; //IBTable
    dmDatos.transFleetDB.Commit; //IBTransaction
    dmDatos.tblEmpleados.Active := False;
End;

El código funciona. Ahora bien...es la manera correcta de hacerlo????? En el método GuardarEmpleado de la clase Empleado, defino tblEmpleados.... para pasar los datos a la base, por lo cual, esta clase no sirve para otra aplicación donde se necesite una clase Empleado; esto ultimo es lo que me hace dudar de si está bien escrito o no. Que consejos pueden darme??


Disculpen las "pifias" que pude haber tenido en la explicación. Muchas gracias.
Responder Con Cita
  #2  
Antiguo 19-02-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola pape19.

Decir la manera "correcta" de hacerlo sería como decir que tu código es incorrecto y no es así, por que como mencionas, funciona bién. Pero creo que se le podrían hacer algunas mejoras.

Si bién está probado, el código siguiente es sólo un ejemplo de guía.
Código Delphi [-]
unit uEmpleado;

interface

uses
  Windows, Messages, SysUtils, Controls;

type
  TDataSetAction = (daEdit, daInsert, daAppend);

type
  TEmpleado = class(TObject)
  private
    FNombre: string;
    FNacimiento: TDate;
    FReferencia: Integer;
    procedure SetNacimiento(const Value: TDate);
    procedure SetNombre(const Value: string);
    procedure SetReferencia(const Value: Integer);
    procedure SetAction(const Value: TDataSetAction);
  public
    constructor Create;
    procedure Save;
    procedure Delete;
    property Action: TDataSetAction write SetAction;
    property Nombre: string read FNombre write SetNombre;
    property Nacimiento: TDate read FNacimiento write SetNacimiento;
    property Referencia: Integer read FReferencia write SetReferencia;
    destructor Destroy; override;
  end;

implementation

uses Unit3; // DataModule

constructor TEmpleado.Create;
begin
  inherited;
  with DataModule1 do
  begin
    if not IBTransaction1.InTransaction then
      IBTransaction1.StartTransaction;
    IBDataSet1.Open;
  end;
end;

procedure TEmpleado.SetAction(const Value: TDataSetAction);
begin
   with DataModule1.IBDataSet1 do
    case Value of
      daEdit: Edit;
      daInsert: Insert;
      daAppend: Append;
    end;
end;

procedure TEmpleado.SetNombre(const Value: string);
begin
  if Value <> FNombre then
    FNombre := Value;
end;

procedure TEmpleado.SetNacimiento(const Value: TDate);
begin
  if Value <> FNacimiento then
    FNacimiento := Value;
end;

procedure TEmpleado.SetReferencia(const Value: Integer);
begin
  if Value <> FReferencia then
    FReferencia := Value;
end;

procedure TEmpleado.Save;
begin
  if Nombre = EmptyStr then
    raise Exception.Create('Error: Nombre es un dato requerido');
  // aquí pueden ir otras comprobaciones...
  with DataModule1 do
  begin
    IBDataSet1.FieldByName('REFERENCIA').AsInteger := Referencia;
    IBDataSet1.FieldByName('NOMBRE').AsString   := Nombre;
    IBDataSet1.FieldByName('FECHA_NAC').AsDateTime := Nacimiento;
    IBDataSet1.Post;
  end;
end;

procedure TEmpleado.Delete;
begin
  if MessageBox(0,'¿ Desea eliminar el registro ?',
                '',MB_ICONQUESTION+MB_YESNO)= IDYES then
    DataModule1.IBDataSet1.Delete;
end;

destructor TEmpleado.Destroy;
begin
  with DataModule1 do
  begin
    IBDataSet1.Close;
    IBTransaction1.Commit;
  end;
  inherited;
end;

end.

Un ejemplo de uso:
Código Delphi [-]
...
implementation

uses uEmpleado;


var
  Empleado: TEmpleado;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Empleado:= TEmpleado.Create;
end;

// Edit
procedure TForm1.btnEditClick(Sender: TObject);
begin
  with Empleado do
  begin
    Action:= daEdit;
    Referencia:= IntToStr(EditRef.Text);
    Nombre:= EditNomb.Text;
    Nacimiento:= DateToStr(EditNac.Text);
    Save;
  end;
end;

// Insert (para Append es igual, solo cambia: Action:= daAppend)
procedure TForm1.btnInsertClick(Sender: TObject);
begin
  with Empleado do
  begin
    Action:= daInsert;
    Referencia:=  IntToStr(EditRef.Text);
    Nombre:= EditNomb.Text;
    Nacimiento:= DateToStr(EditNac.Text);
    Save;
  end;
end;

// Delete
procedure TForm1.btnDeleteClick(Sender: TObject);
begin
  Empleado.Delete;
end;

...

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Empleado.Free;
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 19-02-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
Daniel,



Nelson.
Responder Con Cita
  #4  
Antiguo 19-02-2014
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.278
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Yo creo que la idea es buena. Se pueden modificar algunas cosas, pero el camino es el correcto.
Algunas sugerencias...

(1) En la parte public de tu empleado has definido procedures para rellenar los diferentes "campos". Utiliza propiedades. Si además las colocas en la parte published te permitirá utilizar RTTI para trabajar con ellas. Lo cual te da mucha potencia y es muy útil para trabajar con POO, aunque tal vez eso puedas dejarlo para más adelante. Tal como te ha indicado ecfisa.

(2) Si deseas aprovechar tu clase TCliente en otros lugares, deberías crear una propiedad (o las que necesites) para asignar los componentes de Base de Datos (TDatabase, TDataSet,...). De esa forma si la utilizas en otra aplicación sólo deberás rellenar esas propiedades con los nuevos valores.
De esa forma "extraes" de la clase los elementos "concretos" que la unen a tu aplicación actual y la haces más universal.
Algo así como los parámetros de una función.

(3) Siguiendo con el punto anterior, si cada clase va a taner unas propiedades para la conexión a Base de Datos, lo lógico sería crear una clase "base" que posea los métodos, propiedades y código comunes a todas. De esta forma evitarás mucho código.

(4) Más adelante, si dominas la herencia y con un poco de RTTI, puedes hacer que métodos como el Save, Delete, Buscar,... de la diferentes clases puedan estar codificados casi por completo en la "clase base", de esa forma si tienes 10 clases no tienes que implementarlos en todas ellas.

Código Delphi [-]

  TBaseClass = class (TObject)
    ...    
  public
    property Connection:...
    Property Table:....
  end;

  TCliente = class(TBaseClass)
  private
    ...
  published
    ...
    procedure Save;
    procedure Delete;
    procedure Update;
    ...
  end;
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 21-02-2014
pape19 pape19 is offline
Miembro
 
Registrado: jul 2010
Posts: 96
Poder: 14
pape19 Va por buen camino
Sus respuestas me han orientado muchísimo, sobre todo para poder encontrar información adicional. Por ejemplo, no tenía muy en claro lo que era RTTI; si bien he visto que no es fácil de aplicar, con estudio todo se aprende, y además el esfuerzo vale la pena porque realmente simplifica mucho código y logra aplicaciones con clases más "parametrizables" por decirlo de alguna manera. Lo que lleva a más reutilización, el anhelo de cualquier programador que toma esto como actividad, creo yo.

Dejo un link con un manual que me ha servido mucho para iniciar este camino por la POO en Delphi.

http://delphi.about.com/od/oopindelp...elphi_oop2.htm

En el FTP he subido su traducción:

http://terawiki.clubdelphi.com/Delph...+en+Delphi.rar



Neftalí y ecfisa, muchas gracias! Saludos!
Responder Con Cita
  #6  
Antiguo 22-02-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
pape19,

Cita:
Empezado por pape19
...siento curiosidad por aplicar todos mis conocimientos teóricos aprendidos de POO en la práctica...si bien he visto que no es fácil de aplicar, con estudio todo se aprende...
Revisa estos links:
Cita:
POO en Delphi : http://www.delphiaccess.com/forum/%2...-delphi%29-34/

Run-Time_Type_Information_In_Delphi : http://terawiki.clubdelphi.com/Delph..._In_Delphi.rar

Object Oriented Programming in Delphi: Object_Oriented_Programming_in_Delphi.rar
Espero sea útil

Nelson.

Última edición por Casimiro Notevi fecha: 24-02-2014 a las 00:23:09.
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
Programación orientada a objetos + Aplicacion Ejemplo pape19 Varios 4 19-06-2013 14:13:06
Programacion orientada a Objetos...duda total.... Kenobi Varios 20 30-07-2008 15:38:25
Programacion Orientada A Objetos sdiaz1983 Varios 8 16-11-2007 02:42:46
Es la Programación Orientada a Arquitectura una evolución de OOP? Roll06lm OOP 4 23-10-2007 00:33:50
Programación Orientada a Aspectos marcoszorrilla Debates 17 06-04-2004 23:18:27


La franja horaria es GMT +2. Ahora son las 16:58:58.


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