delphi中的接口和构造函数

pra*_*mer 10 delphi constructor interface

我正在为业务对象编写一个框架.由于以下原因,我大量使用接口:

1)自动内存管理
2)关注点分离

通常构造函数有一些参数是框架的对象,但我不能将它们放在接口中.

我的问题是,如果我使用接口来分离实现它们的类的关注,为什么我的代码最终仍然绑定到实现接口以调用构造函数及其参数的具体类.

将创建者代码放在工厂方法中的优点是什么?(我还没有使用的东西..)

谢谢!

===编辑===

我的问题中的一点是构造函数的参数..在框架中很多对象需要一些其他工作..答案很好地解决了关注点,但我仍然没有看到如何解决参数问题..

如果我不采用构造函数的方式,我应该在对象的每个方法中使用"过程初始化"方式(在界面中)和"CheckObjectInitialized"(受保护).这怎么会更干净?

Mar*_*ema 8

Factory方法允许您在一个地方注册接口的实现者,并允许其余代码"只需要一个实现者".

Factory.GetImplementorOf(IMyInterface)
Run Code Online (Sandbox Code Playgroud)

然后返回一个接口引用.

您需要如何实施工厂.您可以为所请求的每个接口创建新实例,维护已创建实例的池并返回对这些实例的引用,或根据请求的接口进行混合.

您还可以决定是否希望工厂允许同一接口的多个实现者(如何选择正确的接口)或为每个接口或混合强制实施单个实现者.

多个实例可以派上用场,例如在处理可能无法使用的重复(d)服务时,您可以选择一个恰好可能的服务.

提供GetImplementorOf(接口数组)也可能是一个想法.因此,您可以拥有IDump的多个实现者,但通过它们转储信息的方式区分它们:例如,IDump是IHTML格式的对象的实现者.


工厂是否准备以一些干净的方式使用构造函数参数?

那么现在,这是一个有趣的问题.不,他们自己也不是.工厂通常使用标准构造函数,可能采用"所有者"和/或"Id"参数.

如果你想在每个类的基础上有更多特定的构造函数,你必须这样做

  • 创建更多的工厂,这就失去了注册接口实现者的单一目的的目的
  • 允许在每个接口/类的基础上构建初始化方法,这些方法应该在构造之后立即调用,这样可以使代码打开以便忘记并使类更不可变.
  • 或者想出一种将构造函数签名知识纳入工厂的方法.

在一个阶段,我选择了第三个选项.通过创建一个工厂

  • 需要注册具有抽象基类的接口
  • 必需的实现者来自抽象基类
  • 将实现者作为元类引用而不是实例返回
    TFactory = class(...)
    public
      procedure RegisterInterface(const aGUID: TGUID; const aAbstractBase: TClass);
      procedure RegisterImplementor(const aGUID: TGUID; const aImplementor: TClass);
      function GetImplementor(const aGUID: TGUID): TClass;

缺点:

  • 必须声明接口和抽象基类是相当大的拖累.
  • 它破坏了单一继承语言中接口的"多重继承"优势.
  • 您需要在整个代码中传播接口/抽象基类对的知识,否则您仍然无法使用特定于类的构造函数.泛型可能在这里有所帮助,但我还没有调查过.
  • 如果您没有相同(一组)接口的多个实现者,那么它没有用处.
  • 即使您只需要多个实现器进行单元测试,它似乎也有些过分.我发现在测试单元中声明的虚拟类与类的接口的相关部分更有帮助和有效.

总而言之,我已经回到标准构造函数/特定的初始化对方法.编写代码扫描单元测试以检查来自工厂的每个GetImplementor调用是否跟随初始化调用应该相当容易.尽管理论上的类不再像使用特定构造函数那样不可变,但它仍然适用于所有实际目的.如果你想确保只在构造后立即调用Initialize方法,那么应该很容易添加.