Delphi,Win32应用,Server 2005数据库。
我正在实施一个质量管理体系。我有一些预定义的进程映射可以在我的应用程序/系统中应用它们。我被要求拥有所有的事务(我不确定它是否是正确的词)动态的,所以每当他们修改进程映射时,它就会影响应用程序(当然没有重新编译或任何补丁)。
下面是一个更清楚地解释的例子:
假设有一个文档控制模块,我们有一个流程图,如下所示:
文档控制器( document Controller )从Contractor
现在,应用程序应该从数据库中读取参数以获得其功能。假设接收并检查了文档(1和2),现在发送它。一旦按下“保存”按钮,系统就应该检查该文档的接收方,并将文档发送给他/她。在我们的示例中,接收方是项目经理。但是,稍后他们可能会决定更改流程图,作为“3文档控制器将文档发送给Project”。因此,系统应该按照流程图中定义的那样工作。
我想知道实现这种系统的正确方法是什么(Delphi,win32)?
我有一些想法,但不确定它是否合适:对于流程映射中的每个进程,我可以定义一个具有某种唯一Id的服务,然后从数据库中读取该服务并在应用层调用它(包含相关参数)。在这种情况下,我不确定每个服务是否应该是一个dll或包文件,而且我认为拥有这个数量的库文件是错误的,因为服务将不会非常少!
我希望我能很好地解释我的问题,如果时间太长,我很抱歉。如果不清楚,请告诉我。
谢谢,
马海亚
发布于 2011-06-27 13:55:06
在我看来,您想为应用程序执行的每个“业务功能”应用一些通用规则,从而实现某种形式的质量管理。我将使用“业务函数”来表示一个逻辑操作,它可能跨越源代码中的几个技术功能和过程。
没有明确的“正确的方法”,但有些想法比其他的好。
使用数据库来存储动态数据显然是个好主意。例如,您可以将每个业务函数建模为一个单独的实体(每个业务函数有一个数据库记录)。无论您需要什么变量来管理每个业务函数的处理,都将确定必要的字段。你肯定需要为每个人都提供一个独特的身份。
没有理由将业务函数编码到单独的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;这样,随着运行时参数在数据库中的变化,应用程序的行为将有所不同,而不需要重新编译。
https://stackoverflow.com/questions/6249832
复制相似问题