Ejemplo de Delphi refactorización relativa a los datos controles conscientes y Módulos de Datos con acceso directo a las tablas db

StackOverflow https://stackoverflow.com/questions/4051810

Pregunta

Estoy tratando de definir la mejor manera de refactorizar el proyecto en el que estoy trabajando.

Debido a la falta de un buen diseño casi todos los proyectos se compone de:

1) formas que contienen la lógica de negocio

2) enormes Módulos de Datos (1 por la forma + algunos más)

3) algunas unidades que contienen código común (bibliotecas)

No hay programación orientada a objetos (a excepción de algunas áreas pequeñas), la reutilización de código que está a un nivel mínimo.

Un problema es también que se utilizan DataAware controles, por lo que era muy fácil de soltar muchos conjuntos de datos + fuentes de datos en los Módulos de Datos y enlace directamente a la DB de una manera altamente acoplado.

Tu lugar ideal para extraer clases, como TCustomer, TEmployee, para conseguir la encapsulación ventaja OS y para que sea posible crear nueva interfaz de usuario en el futuro sin duplicar todo el código.

De todos modos mi pregunta es: ¿Cómo se puede mantener a tratar con DataAware controles? Debería implementar una función que devuelve un conjunto de datos, y vincular el dataawarecomponent.datasource al resultado de la función?

function TCustomer.LoadByID(aCustomerID: integer): TDataset

¿Fue útil?

Solución

Usted está obligado a la arquitectura de su aplicación fue diseñada alrededor. No trate de luchar contra ella. Deje que los datos de los controles conscientes hacen lo que son buenos, la sincronización de datos. Si los controles ya están obligados a sus fuentes de datos utilizando el DFM no debería ser un problema.

Lo que se hace necesario refactorizar es cualquier controlador de eventos que haya conectado a sus controles. Le sugiero que tome un vistazo a la Supervisar patrón Controlador . He encontrado ejemplos de implementaciones para:

  • ASP.NET
  • . NET (ya sea winforms o wpf) clientes Rich
  • Smalltalk (éste fue pionera en el patrón y es anterior a la etiqueta de "controlador supervisor)

Si bien hay algunos ejemplos de patrones arquitectónicos de interfaz de usuario en Delphi aquellas que están orientadas hacia las aplicaciones de escritorio tienden a ser sobre la pasivo Ver en lugar de Supervisión del controlador. Así que aquí es mi opinión sobre ella.

Usted querrá comenzar con la definición de al menos una interfaz para cada forma en su aplicación. Digo al menos un porque algunas formas son complejas y pueden necesitar ser dividida en múltiples interfaces.

IProductView = interface
end;

A continuación, haga que su forma de ponerla en práctica.

TProductForm = class(TForm, IProductView)
...
end;

A continuación, tendrá un presentador / controlador. Este se encargará de todo, excepto la sincronización de datos.

TProductPresenter = class
private
  FView: IProductView;
public
  constructor Create(AView:IProductView);
end;

Crear un campo privado en su clase de formulario y crear / liberar el presentador cuando se crea el formulario / liberado. Ya sea que utilice de forma constructor / destructor o los alcrear / OnDestroy eventos no importa mucho.

TProductForm = class(TForm, IProductView)
private
  FPresenter: TProductPresenter;
public
  constructor Create;
...
end;

implementation
TProductForm.Create
begin
  FPresenter := TProductPresenter.Create(self);
end;

Ahora cuando se necesita el formulario o uno de sus controles para responder a un evento de la responsabilidad delegada al presentador. Asumamos que es necesario comprobar que el nombre del producto utiliza la capitalización adecuada.

TProductForm.NameDBEditChange(Sender: TObject);
begin
  FPresenter.ValidateName;
end;

En lugar de pasar el control o la propiedad de texto como argumento que exponen los datos como una propiedad en la interfaz ...

IProductView = interface
  function GetName:string;
  procedure SetName(Value: string);
  property Name: string read GetName write SetName;

... e implementar GetName y SetName en el formulario.

TProductForm.GetName: string;
begin
  Result := NameDBEdit.Text;
end;

TProductForm.SetName(Value: string);
begin
  NameDBEdit.Text := Value;
end;

Es importante exponer los datos en la forma más simple posible. Usted no quiere que el presentador en función del nombre del producto que se almacena en un TDBEdit. El presentador sólo debe ver lo que permite explícitamente a ver a través de la interfaz. La principal ventaja de esto es que puede modificar la forma tanto como usted desee (o sustituirla por completo) y siempre que se adhiere a la interfaz tendrá que ser hecha al presentador sin cambios.

Ahora que toda su lógica de negocio se ha movido a su presentador que se asemejará a una clase de dios. Su próximo paso será refactor que la lógica en clases apropiadas rotos por la responsabilidad. Al llegar a este punto, usted está en una mejor posición mucho para intentar un nuevo diseño arquitectónico (si su aún teniendo en cuenta que).

"WOW! Que se parece a un montón de trabajo!" tu podrias decir. Estaríamos en lo cierto (pero entonces se sabía que sería mucho trabajo antes de que empezaste). No tiene que hacer todo a la vez. Ninguno de estos pasos está cambiando el comportamiento de la lógica justo donde se lleva a cabo.

Ventajas

  • interfaz de usuario ahora es fácil de modificar
  • La lógica de negocio puede más fácilmente ser probado de manera aislada
  • se puede implementar de forma incremental

Desventajas

  • Es más trabajo en un primer momento, pero esto se compensa con el tiempo más maicódigo ntainable más adelante.
  • No es adecuado para todas las aplicaciones. Para proyectos pequeños de la infraestructura adicional puede no valer la pena el esfuerzo.

Otras referencias

Otros consejos

Si no hay un buen diseño y programación orientada a objetos no real en el código a continuación, teniendo en cuenta su complejidad, primero debe empezar por crear un diseño que describe su funcionalidad actual. Sí, eso significa que será ocupado escribiendo un montón de documentación en un principio. Pero que le permite dividir el proyecto en partes lógicas / funcionales que se podría utilizar para centrarse en vez finalizada esta documentación. A continuación, podría refactorizar cada parte por separado, o posiblemente incluso reescribir esas partes.
Proyectos este complejo no siempre son prácticos para refactorizar. Usted debe volver al diseño original (por lo tanto crearlo ya que no tiene ninguno) y luego ver su código y considerar lo que es más rápido: refactorización o volver a escribir ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top