【问题标题】:What Design Patterns do you implement in common Delphi programming? [closed]您在常见的 Delphi 编程中实现了哪些设计模式? [关闭]
【发布时间】:2010-12-07 18:23:45
【问题描述】:

您在常见的 Delphi 编程中实现了哪些设计模式?哪些模式在 Delphi 编程中更容易适应? (每种语言在不同领域都表现出色,那么在使用 Delphi 时,哪些模式可能是非常强大的结构?)

如果您能告诉我 Delphi 2009 / 2010 设计模式的一些变化(因为那些支持泛型和 2010 年的 RTTI),我会很高兴。

在网上有很多文章,但它们没有讨论日常可用性和模式的变化。 (他们中的大多数只是讨论语言细节、架构的变化)。

【问题讨论】:

  • 也许这应该是一个社区 wiki 问题
  • 我能问一下为什么吗?我在问一个具体的问题,处理 Delphi 的设计模式,以及自从 Delphi 语言(2009 年、2010 年)发生变化后它们是否发生了变化
  • 嗯,不,Juraj,你不是在问一个具体的问题。我数了至少 三个 问题,而且它们都是相当开放的。不过,不确定这是否是制作社区 wiki 的理由。
  • 移到 CW,只是想知道,如果有人知道 Delphi 2009/2010 中的模式变化

标签: delphi design-patterns


【解决方案1】:

只有少数 Delphi 开发人员知道每个 Delphi 开发人员都使用 Factory pattern(delphi.about.com 有一个 example in "regular" Delphi),但随后使用虚拟 Create 构造函数实现。

所以:是时候阐明这一点了 :-)

虚拟构造函数之于类,就像虚拟方法之于对象实例。

工厂模式的整个想法是,您将确定要创建哪种(在本例中为“类”)事物(在本例中为“对象实例”)的逻辑与实际创建解耦。

使用虚拟 Create 构造函数的工作方式如下:

TComponent 有一个virtual Create constructor 所以,它可以被任何降序类覆盖:

type
  TComponent = class(TPersistent, ...)
    constructor Create(AOwner: TComponent); virtual;
    ...
  end;

例如 TDirectoryListBox.Create constructor 覆盖它:

type
  TDirectoryListBox = class(...)
    constructor Create(AOwner: TComponent); override;
    ...
  end;

您可以将类引用(类与对象实例引用的类比)存储在“类类型”类型的变量中。对于组件类,有一个预定义类型TComponentClass in the Classes unit

type
  TComponentClass = class of TComponent;

当你有一个 TComponentClass 类型的变量(或参数)时,你可以进行多态构造,这与工厂模式非常相似:

var
  ClassToCreate: TComponentClass;

...

procedure SomeMethodInSomeUnit;
begin
  ClassToCreate := TButton;
end;

...

procedure AnotherMethodInAnotherUnit;
var
  CreatedComponent: TComponent;
begin
  CreatedComponent := ClassToCreate.Create(Application);
  ...
end;

Delphi RTL 在这里使用这个例子:

Result := TComponentClass(FindClass(ReadStr)).Create(nil);

这里:

// create another instance of this kind of grid
SubGrid := TCustomDBGrid(TComponentClass(Self.ClassType).Create(Self));

Delphi RTL 的第一个用途是从 DFM 文件中读取的表单、数据模块、框架和组件的整个创建过程如何工作。

表单(datamodule/frame/...)类实际上有一个(已发布)表单(datamodule/frame/...)上的组件列表。该列表包括每个组件的实例名称和类引用。 在读取 DFM 文件时,Delphi RTL 会:

  1. 查找组件实例名称,
  2. 使用该名称来查找基础类引用,
  3. 然后使用类引用动态创建正确的对象

普通的 Delphi 开发人员通常不会看到这种情况发生,但没有它,整个 Delphi RAD 体验就不会存在。

Allen Bauer(Embarcadero 的首席科学家)也写了一个简短的blogarticle about this topic。 还有一个关于where virtual constructors are being usedSO 问题。

让我知道这对虚拟创建构造函数主题是否足够了解:-)

--杰罗恩

【讨论】:

  • 可惜我只能投票一次,很棒的帖子,谢谢
  • @Tom 感谢您的编辑;有点词盲,这些正是我一直忽略的。
  • 很好的例子。需要注意的一件事。其他语言中的工厂模式实现使用普通的静态函数(或用于 pascalites 的 class 函数)。因此,它们能够返回 null(nil)。 Delphi 构造函数,就像其他语言中的无名构造函数一样,将始终返回对象引用,除非您引发异常。当然,如果需要,您可以随意使用类函数。
【解决方案2】:

您可以在 GOF 模式和 Delphi 习语的等价性上找到an excellent article by Marco Cantu。我记得参加过他关于这个主题的 Borcon 会议,非常棒。
要记住的一个主要思想是需要设计模式来补充语言/框架的缺点。如果你有一个本地习语,你不需要重新发明轮子并实现整个 GOF shebang,只需学会识别它并命名它(就像 Jeroen 用他的superb explanation on the Factory 所做的那样)。

【讨论】:

    【解决方案3】:

    我经常使用以下模式:

    • 命令
    • 访客
    • 表数据网关
    • 观察者
    • 适配器
    • 单身人士(非常小心!)
    • 抽象工厂
    • 工厂方法
    • 状态
    • 所有形式的依赖注入
    • 立面
    • 服务定位器
    • 分离界面

    【讨论】:

      【解决方案4】:

      我经常使用以下模式:

      1. MVC 中的观察者
      2. 单顿
      3. 模板方法
      4. 状态

      【讨论】:

      • 有一个关于单身人士的答案,它说,他们是纯粹的邪恶。伪装的全局变量:)
      • 如果你滥用它们,两者都是邪恶的。在某些情况下,单例非常方便。
      【解决方案5】:

      非 OOP 编程(有人称之为结构化编程)在 Delphi 程序员中非常常见。这很简单:你创建一个函数来做某事,它与记录/对象类数据结构无关。示例:IntToStr()

      Delphi 在这方面做得很好,因为封装是使用接口/实现部分提供的,而且生成的机器代码非常高效。编译时,它还支持优化,例如,如果您的接口部分中有一个类型化常量,并且程序已完全编译 - 如果您随后更改该常量的值,则不会重新编译该单元,仅重新编译该常量变化。这在日常工作中并不是真正需要的,但它是 Delphi 工作原理的一个示例。

      【讨论】:

      • 这个答案与问题中提到的任何主题有什么关系?
      • 非 OOP 不一定是“结构化编程”。例如,还有函数式编程,对于寻求学习“外星人”东西的 Delphi 程序员来说,这是一个非常有趣的话题。查看delphifeeds.com/go/s/44177 了解面向 Delphi 开发人员的介绍。
      • -1 根本不是设计模式
      • @Jeroen:KISS 不在 GoF 书中,因为它根本不是一个可识别的模式。这是一个好主意,是的,但是模式就像是处理一类问题的常见且经过验证的解决方案的句柄。模式旨在帮助人们解决问题并就此进行交流,仅仅抛出“KISS”两者都没有。
      • Lars,正如“非面向对象编程”和“保持简单”不是模式,重构也不是。而且你真的应该关心什么叫什么——模式的全部意义在于它们为我们提供了一个通用词汇,供我们在思考和讨论问题时使用。使用与世界上最流行的模式书所使用的名称不同的名称对任何人都没有帮助。您已经做出了几个正确的陈述 - 可以按照您的描述重构一个过程,并且非 OOP 非常常见 - 但它们如何相关 i> 手头的问题?
      【解决方案6】:

      一个普通的Unit 表现得像一个单身人士。虽然你不能使用像继承和多态这样的 OOP 技术,但这可能是件好事 :)

      我通常认为 Delphi 很容易避免健全的 oop 设计。这对 RAD 来说很好,但是如果您想要一个灵活且可维护的代码,您需要知道要避免哪些陷阱。例如,您添加到表单的组件的公开可见性、类型为 TForm1 的全局 Form1 变量(而不是手动管理的生命周期和作为类型的基类)以及 GUI 和业务逻辑之间缺乏分离。只是提一些问题。

      【讨论】:

        猜你喜欢
        • 2014-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-27
        相关资源
        最近更新 更多