2011-06-06 8 views
5

Aplicación Delphi XE, Win32, base de datos de SQL Server 2005.Implementación de mapa de proceso dinámico para la aplicación win32 utilizando Delphi

Estoy implementando un Sistema de gestión de calidad. Tengo algunos mapas de proceso predefinidos para aplicarlos dentro de mi aplicación/sistema. Se me solicita que tenga todas las transacciones (no estoy seguro si es la palabra correcta) dinámicas así que cuando modifiquen los mapas de proceso afecta la aplicación (sin recompilación o cualquier parche de curso)

Aquí hay un ejemplo para explicar más claro:

asumir un módulo de control de documentos, tenemos un mapa de procesos como:

  1. [documento controlador] Recibe el documento del contratista
  2. [documento controlador] Comprueba el documento con la lista de comprobación
  3. [Documento Controlador] envía el documento a la [director de proyecto]
  4. [director de proyecto] se aplica y acción en el documento
  5. [jefe de proyecto] envía el documento a [responsable del documento]
  6. [responsable del documento] Archiva el documento.

Ahora la aplicación debe leer los parámetros de una base de datos para conocer sus funciones. Digamos Recibido y Comprobado el documento (1 y 2) y ahora lo envía. Tan pronto como se presione el botón "Guardar", el sistema debe verificar quién debe ser el receptor de este documento y enviarle el documento. En nuestro ejemplo, el receptor es el [project Manager]. sin embargo, en algún momento más tarde podrían decidir cambiar el mapa de proceso como - "3- [Controlador de documentos] envía el documento al [Arquitecto del proyecto]". Por lo tanto, el sistema debe actuar como se define en el mapa de proceso.

Me pregunto cuál es la forma correcta de implementar dicho sistema (Delphi XE, win32)?

Tengo una idea pero no estoy seguro si es correcta: Para cada proceso en el mapa de proceso puedo definir un servicio con un tipo de Id único y leer el servicio de la base de datos y llamarlo en la capa de aplicación (con los parámetros relevantes). En este caso, no estoy seguro de si cada servicio debe ser un archivo dll o paquete y creo que es incorrecto tener esa cantidad de archivos de la biblioteca, ¡ya que los servicios van a ser muy pocos!

Espero poder explicar bien mi problema y disculparme si es demasiado largo. Por favor, hágamelo saber si no está claro.

Gracias,
Mahya

+2

Creo que esta es una cuestión de arquitectura en lugar de uno de codificación y, por lo tanto, no es adecuado para Stack Overflow. –

+1

Quizás relacionado o útil: _ ¿Existe una implementación de "Motor de flujo de trabajo" para Delphi? "_ (Http://stackoverflow.com/questions/3492725/is-there-a-workflow-engine-implementation-for-delphi) – mjn

Respuesta

2

Me suena como que desea aplicar algunas reglas comunes para cada "evento de negocios", interpretada por su aplicación, aplicando de esta forma algún tipo de gestión de la calidad. Voy a utilizar "función comercial" para denotar una operación lógica que puede abarcar varias funciones técnicas y procedimientos en el código fuente.

No existe una "forma correcta" definida, pero algunas ideas son mejores que otras.

El uso de una base de datos para almacenar datos dinámicos es obviamente una buena idea.Por ejemplo, puede modelar cada función comercial como una entidad separada (con un registro de base de datos por función comercial). Cualquier variable que necesite para administrar el procesamiento de cada función de negocio determinará los campos necesarios. Definitivamente necesitarás una identificación única para cada uno.

No hay ninguna razón para codificar las funciones comerciales en dlls separadas, pero las pondría en unidades separadas en el código fuente o quizás agrupe las funciones según su tipo de operación o alguna otra agrupación lógica que tenga sentido para su negocio. Tendrá que cambiar la forma en que llama a las funciones de su negocio. Necesitará llamarlos indirectamente, en otras palabras, llamaría a una rutina genérica PerformFunction, tal vez pasando un identificador de función y algunos otros parámetros en la estructura de datos que le convenga. A medida que se cambian los parámetros en la base de datos (de acuerdo con su ejemplo, ¿a quién enviar el documento, Project Manager o Project Architect?) La operación de la función comercial se modificará en consecuencia siempre que haya implementado todas las permutaciones posibles que podría surgir dado el número de variables para cada función comercial. Estoy seguro de que la dirección de correo electrónico del destinatario del documento no es todo lo que tiene en mente. Aquí hay un código que podría ayudar. No digo que sea un buen código, es solo para transmitir la idea.

type 
    TFunctionRuntimeParameter = record 
    FunctionID: integer; // this better be unique 
    FunctionName: string; // something intelligible for display purposes 
    ReportToEmail: string; // who to send the end report document 
    AuditLevel: integer; // for example vary the degree of auditing/logging 
    variableABC: TDateTime; // could be a date that influences something 
    end; 

function TMyForm.GetRuntimeParametersFromDB(aFunctionID: integer): TFunctionRuntimeParameters; 
var 
    tempResult: TFunctionRuntimeParameters; 
begin 
    // For brevity I'm going to assume an existing query object connected to your db. 
    qry.SQL.Add('Select * From BusinessFunctions Where Function_ID = :FunctionID'); 
    qry.ParamByName('FunctionID').AsInteger := aFunctionID; 
    qry.Open; 
    tempResult.FunctionID := qry.FieldByName('Function_ID').AsInteger; // don't ask me Y! 
    tempResult.FunctionName := qry.FieldByName('Function_Name').AsString; 
    tempResult.ReportToEmail := qry.FieldByName('Report_To_Email').AsString; 
    tempResult.AuditLevel := qry.FieldByName('Audit_Level').AsInteger; 
    tempResult.variableABC := qry.FieldByName('ABC').AsDateTime; 
    result := tempResult; 
    qry.Close; 
end; 

procedure TMyForm.PerformFunction(aFunctionID: integer; FRP: TFunctionRuntimeParameters); 
var 
    MyReportDocument: TMyReportDocument; 
begin 
    if (FRP.AuditLevel > 0) then 
    // do something special before starting the function 

    case aFunctionID of 
    101: MyReportDocument := DoBusinessFunctionABC; 
    102: MyReportDocument := DoBusinessFunctionDEF; 
    103: MyReportDocument := DoBusinessFunctionXYZ; 
    end; 

    SendReportDocumentByEmailTo(MyReportDocument, FRP.ReportToEmail); 

    if ((Now - FRP.variableABC) > 28) then 
    // perhaps do something special every 4 weeks! 

    if (FRP.AuditLevel > 0) then 
    // do something special after the function has finished 
end; 

procedure TMyForm.btnBusinessFunctionXYZClick(Sender: TObject); 
var 
    FunctionID: integer; 
    FunctionRuntimeParameters: TFunctionRuntimeParameters; // record that mimics db entry 
begin 
    FunctionID := 1234; // or you might prefer an enum 
    FunctionRuntimeParameters := GetFunctionRuntimeParametersFromDB(FunctionID); 
    PerformFunction(FunctionID, FunctionRuntimeParameters); 
end; 

esta manera como el cambio de parámetros de ejecución en la base de datos, la aplicación se comportará de manera diferente sin necesidad de recompilación.

Cuestiones relacionadas