delphi - 使用Delphi实现win32应用程序的动态流程图

标签 delphi architecture workflow software-design

Delphi XE、Win32 应用程序、SQL Server 2005 数据库。

我正在实现质量管理体系。 我有一些预定义的流程图可以将它们应用到我的应用程序/系统中。我被要求将所有事务(我不确定它是否是正确的词)动态化,因此每当他们修改流程图时,它都会影响应用程序(当然无需重新编译或任何补丁)

下面是一个例子,可以更清楚地解释:

假设一个文档控制模块,我们有一个流程图:

  1. [文件控制者]从承包商处接收文件
  2. [文档 Controller ]使用 list 检查文档
  3. [文档 Controller ] 将文档发送给[项目经理]
  4. [项目经理]在文档中应用并执行操作
  5. [项目经理]将文档发送到[文档 Controller ]
  6. [文档 Controller ] 归档文档。

现在应用程序应该从数据库中读取其功能的参数。 假设已收到并检查了文档(1 和 2),现在将其发送。一旦按下“保存”按钮,系统就会检查谁应该是该文档的接收者并将文档发送给他/她。 在我们的示例中,接收者是[项目经理]。然而,稍后他们可能会决定将流程图更改为 - “3- [文档控制者] 将文档发送给 [项目架构师]”。 因此,系统应按照流程图中的定义运行。

我想知道实现这样的系统(Delphi XE,win32)的正确方法是什么?

我有一些想法,但不确定是否正确: 对于流程图中的每个流程,我可以定义一个具有唯一 ID 的服务,然后从数据库读取该服务并在应用程序层中调用它(带有相关参数)。在这种情况下,我不确定每个服务是否应该是一个 dll 文件或包文件,并且我认为拥有这么多库文件是错误的,因为服务不会很少!

我希望我能很好地解释我的问题,如果太长,抱歉。 如果不清楚,请告诉我。

谢谢,
玛雅

最佳答案

在我看来,您希望为应用程序执行的每个“业务功能”应用一些通用规则,从而实现某种形式的质量管理。我将使用“业务功能”来表示可能跨越源代码中的多个技术功能和过程的逻辑操作。

没有定义的“正确方法”,但有些想法比其他想法更好。

使用数据库来存储动态数据显然是一个好主意。例如,您可以将每个业务功能建模为一个单独的实体(每个业务功能有一个数据库记录)。无论您需要什么变量来管理每个业务功能的处理,都将确定必要的字段。您肯定需要为每个人提供一个唯一的 ID。

没有理由将业务功能编码到单独的 dll 中,但我会将它们放在源代码中的单独单元中,或者根据功能的操作类型或对您的业务有意义的其他一些逻辑分组来对功能进行分组。您需要更改调用业务功能的方式。您需要间接调用它们,换句话说,您将调用通用的 PerformFunction 例程,可能会以适合您的任何数据结构传递函数标识符和一些其他参数。随着数据库中参数的更改(根据您的示例,将文档发送给谁,项目经理还是项目架构师?),只要您实现了所有可能的排列,业务功能的操作就会相应地修改考虑到每个业务功能的变量数量,可能会出现这种情况。我确信文档收件人的电子邮件地址并不是您所想到的全部。这是一些可能有帮助的代码。我并不是说这是好的代码,只是为了传达这个想法。

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;

这样,当数据库中的运行时参数发生更改时,应用程序的行为就会有所不同,而无需重新编译。

关于delphi - 使用Delphi实现win32应用程序的动态流程图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6249832/

相关文章:

java - Web 服务前面的数据库级别的数据完整性

asp.net - Entity Framework 4 - 从模型更新数据库架构。不删除表数据

java - "Sequential instead of Parallel Execution"不起作用的 JBPM 多实例循环特性

database - 使用事务和数据感知组件编写 Delphi 数据库应用程序的首选方法

delphi - 将二进制数据传递给 D7 中的 dll 函数

android - 如何以编程方式在互联网上按下按钮

architecture - 业务层逻辑 (BLL) 是关于数据的吗?

javascript - Ember.js:如何为这个例子建模?

sharepoint - 以编程方式将 SharePoint 工作流添加到列表

delphi - 寻找有关使用 Delphi Indy 的书籍