我应该使用类或方法来包装动态远程过程调用吗?

发布于 2025-01-04 03:54:55 字数 1077 浏览 2 评论 0原文

情况

我想让 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 - 类每个函数都

需要

  • 更多代码。
  • 必须创建一个占用内存的对象。

专业人士

  • 阅读代码更容易,您不必查看声明来了解参数是什么。

方法 2 - 包装方法

Contra

  • 您无法仅通过查看代码来判断使用了哪些参数。

Pro

  • 需要编写的代码少得多。
  • 包装器更薄(无需创建任何对象)。

我应该使用哪种方法?

Situation

I'd like to make an RPC interface easier to use. This is a custom interface so there is no readily available wrapper.

I have to write several wrappers around functions which often have many arguments.

Possible solutions

Solution 1 - Using a class for each function:

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

The caller has to create an object to call the function:

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

Method 2 - Using a wrapper method for each function:

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

The caller can simply call it:

TRPCInterface.DoSomething(0, ...);

Pro and contra

Method 1 - Class for each function

Contra

  • More code required.
  • An object must be created which takes up memory.

Pro

  • Reading the code is easier, you don't have to look at the declaration to see what the arguments are.

Method 2 - Wrapper method

Contra

  • You can't tell which arguments are used by just looking at the code.

Pro

  • Much less code to write.
  • The wrapper is thinner (no object has to be created).

Which method should I use?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兔姬 2025-01-11 03:54:55

有一个中间解决方案,即调用传递对象参数的包装器方法。

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

procedure TRPCInterface.DoSomething(Args: TDoSomethingArgs);

此方法的优点之一是您仍然使用方法,但仍然更具可读性。
在参数中使用类(您也可以使用记录)的一个优点是您可以稍后更改参数(添加更多,更改行为),并且如果您选择得好,它不会破坏向后兼容性 - 总之您可以更改方法签名无需破坏代码。

There is an intermediate solution that is calling the wrapper methods passing an object argument.

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

procedure TRPCInterface.DoSomething(Args: TDoSomethingArgs);

one advantage of this method is that you still use methods, but still it's more readable.
One advantage of using classes (you can also use records) in arguments is that you can later change the arguments (add more, change behavior) and if you choose it well, it does not break backward compatibility - in summary you can change method signature without breaking code.

云裳 2025-01-11 03:54:55

你还没有指定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);

:这样你将不得不编写更多代码,但恕我直言,它的可读性要强得多,并且很容易被其他开发人员采用将来。

注意:我还没有测试过这段代码,所以它很可能无法编译。

这是我的两分钱,我很好奇其他人的想法(:

You haven't specified Delphi version, but if yours supports generics, I would go with:

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;

implementation

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

you can use:

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

in this way you will have to write more code, but it's much more readable IMHO and easy to be picked up by other developers in the future.

NOTE: that I haven't tested this code, so chances are that it won't compile.

That's my two cents, I'm very curios as to what others come up with (:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文