Реализация динамической карты процессов для приложения win32 с использованием Delphi - PullRequest
5 голосов
/ 06 июня 2011

Delphi XE, приложение Win32, база данных SQL Server 2005.

Я внедряю систему менеджмента качества. У меня есть несколько предопределенных Карт процессов, чтобы применить их внутри моего приложения / системы. Меня просят сделать все транзакции (я не уверен, что это правильное слово) динамическими, поэтому, когда они изменяют карты процессов, это влияет на приложение (без перекомпиляции или каких-либо исправлений, конечно)

Вот пример, чтобы объяснить более ясно:

Предположим, модуль управления документами, у нас есть карта процесса:

  1. [Контроллер документов] Получает документ от Подрядчика
  2. [Контроллер документов] Проверяет документ с помощью контрольного списка
  3. [Контроллер документов] Отправляет документ в [Менеджер проектов]
  4. [Руководитель проекта] применяется и действие в документе
  5. [Руководитель проекта] Отправляет документ в [Контроллер документов]
  6. [Контроллер документов] Архивирует документ.

Теперь приложение должно считывать параметры из базы данных для своих функций. Допустим, получил и проверил документ (1 и 2) и теперь отправляет его. Как только кнопка «Сохранить» нажата, система должна проверить, кто должен быть получателем этого документа, и отправить документ ему / ей. В нашем примере получателем является [менеджер проекта]. однако через некоторое время они могут решить изменить карту процесса как - «3- [Document Controller] отправляет документ в [Project Architect]». Следовательно, система должна действовать так, как определено в карте процесса.

Мне интересно, как правильно внедрить такую ​​систему (Delphi XE, win32)?

У меня есть идея, но я не уверен, что это правильно: Для каждого Процесса в карте процессов я могу определить Сервис с уникальным идентификатором, прочитать сервис из базы данных и вызвать его на прикладном уровне (с соответствующими Параметрами). В этом случае я не уверен, должен ли каждый сервис быть dll или файлом пакета, и я считаю, что неправильно иметь такое количество библиотечных файлов, так как сервисов будет не очень мало!

Я надеюсь, что смогу хорошо объяснить свою проблему и извините, если она слишком длинная. Пожалуйста, дайте мне знать, если это не ясно.

Спасибо
Махя

1 Ответ

2 голосов
/ 27 июня 2011

Мне кажется, что вы хотите применить некоторые общие правила для каждой «бизнес-функции», выполняемой вашим приложением, тем самым реализуя некоторую форму управления качеством. Я собираюсь использовать «бизнес-функцию» для обозначения логической операции, которая может охватывать несколько технических функций и процедур в исходном коде.

Не существует определенного «правильного пути», но некоторые идеи лучше, чем другие.

Использование базы данных для хранения динамических данных, очевидно, хорошая идея. Например, вы можете смоделировать каждую бизнес-функцию как отдельную сущность (с одной записью базы данных на бизнес-функцию). Независимо от того, какие переменные вам понадобятся для управления обработкой каждой бизнес-функции, будут определены необходимые поля. Вам определенно понадобится уникальный идентификатор для каждого.

Нет причин кодировать бизнес-функции в отдельные библиотеки, но я бы поместил их в отдельные блоки в исходном коде или, возможно, сгруппировал функции в соответствии с их типом работы или какой-то другой логической группировкой, которая имеет смысл для вашего бизнеса , Вам нужно будет изменить способ вызова бизнес-функций. Вам нужно будет вызывать их косвенно, другими словами, вы бы вызвали универсальную подпрограмму 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;

Таким образом, при изменении параметров времени выполнения в базе данных приложение будет вести себя по-другому без необходимости повторной компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...