Должен ли я использовать класс или метод для переноса динамического удаленного вызова процедуры? - PullRequest
5 голосов
/ 10 февраля 2012

Положение

Я бы хотел сделать интерфейс RPC более простым в использовании. Это пользовательский интерфейс, поэтому нет доступной оболочки.

Мне нужно написать несколько оберток вокруг функций, которые часто имеют много аргументов.

Возможные решения

Решение 1 - Использование класса для каждой функции:

TDoSomethingFunction = class
public
  property Arg1: Integer;
  property Arg2: string;
  property Arg3: Boolean;
  procedure Run;
end;

Вызывающий должен создать объект для вызова функции:

var
  DoSomething: TDoSomethingFunction;
begin
  DoSomething := TDoSomethingFunction.Create;
  try
    DoSomething.Arg1 := 0;
    ...
    DoSomething.Run;
  finally
  free;
end;

Метод 2 - Использование метода-обертки для каждой функции:

procedure TRPCInterface.DoSomething(AArg1: Integer; AArg2: string; AArg3: Boolean);

Звонящий может просто позвонить:

TRPCInterface.DoSomething(0, ...);

За и против

Метод 1 - Класс для каждой функции

Contra

  • Требуется больше кода.
  • Должен быть создан объект, который занимает память.

Pro

  • Чтение кода проще, вам не нужно смотреть на объявление, чтобы увидеть аргументы.

Метод 2 - Метод обертки

Contra

  • Вы не можете определить, какие аргументы используются, просто взглянув на код.

Pro

  • Гораздо меньше кода для записи.
  • Обертка тоньше (не нужно создавать никаких объектов).

Какой метод мне использовать?

Ответы [ 2 ]

2 голосов
/ 12 февраля 2012

Существует промежуточное решение, которое вызывает методы-обертки, передающие аргумент объекта.

TDoSomethingArgs = class
public
  property Arg1: Integer;
  property Arg2: string;
  property Arg3: Boolean;
end;

procedure TRPCInterface.DoSomething(Args: TDoSomethingArgs);

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

2 голосов
/ 10 февраля 2012

Вы не указали версию Delphi, но если ваша версия поддерживает дженерики, я бы выбрал:

type
  TArgList = class( TDictionary< String, Variant > );

type
  TBaseFunc = class
  private
    FArgs: TArgList;
  public
    function Run: Boolean; virtual; abstract;
  public
    property Args: TVarList read FArgs write FArgs;
  end;

type
  TSpecialFunc = class( TBaseFunc )
  public
    function Run: Boolean; override;
  end;

реализация

function TSpecialFunc.Run: Boolean;
begin
  // here's where you can access args as variants
end;

, которую вы можете использовать:

ASpecialFunc.Args.AddOrSetValue('ArgumentName', 2012);

таким образом вам придется писать больше кода, но это гораздо более читабельно, ИМХО, и в будущем его легко поймут другие разработчики.

ПРИМЕЧАНИЕ: я не тестировал этот кодтак что, скорее всего, он не скомпилируется.

Это мои два цента, мне очень любопытно, что придут другие (:

...