【问题标题】:Delphi: Good pattern/strategy for view <-> model synchronizationDelphi:视图<->模型同步的良好模式/策略
【发布时间】:2010-12-06 11:55:29
【问题描述】:

最近有很多关于模型-视图-控制器、模型-视图-视图模型、模型-视图-演示者等的讨论。

您认为与 delphi 和非数据感知组件一起使用的最佳模式是什么?

你通常如何实现它?

【问题讨论】:

    标签: delphi design-patterns model view


    【解决方案1】:

    您可以在他的被动视图变体中使用模型视图演示者模式。 前段时间我写了一篇关于它的帖子。 http://www.danieleteti.it/?cat=18

    你也可以使用 Model Gui Mediator (http://www.andypatterns.com/index.php/design_patterns/model_gui_mediator_pattern)

    【讨论】:

    • 非常有趣。有时间会仔细看的。
    【解决方案2】:

    MVC 的目的是解耦。解耦系统显然更容易维护,并且可以说更容易开发。你能在不影响你的 GUI 代码的情况下彻底改变你的数据库设计吗?您的 GUI 能否完全改变而不会对您的数据库设计产生太大影响?数据库中数据的一致性是否独立于 GUI 或基于表单的事件发生的顺序?这些才是真正重要的问题,而 MVC 是一种正面回答这些问题的方法。

    我不是专家,但过去我被这几件事烧伤了:

    1. 尝试将所有对 DB 访问和 DB 访问组件的显式引用放入数据模块中。如果你在过多的数据模块方面犯了错误也没关系,但要注意不要在同一个数据模块中放置太多不相关的 DB 访问项(组合代码比分离代码容易得多)。

    2. 虽然在设计时将所有 DB 组件连接到主连接/会话组件非常方便(这样做是 Delphi 的优势之一),但能够显式设置在运行时动态的连接字符串、会话或连接引用,特别是当想要在不同项目中使用数据模块时,无需添加原始项目的数据库连接单元(如果存在)。

    3. 尽最大努力将尽可能少的业务逻辑放入组件事件中。这是不使用数据感知组件的自然延伸。很难坚持这一点,因为始终如一地进行似乎就像是在做额外的工作,尤其是在一个新项目中,并且您告诉自己稍后再重构;当然,你知道那是个谎言,因为以后永远不会来

    第 (3) 点可能需要一个示例。以下两个 sn-ps 在清晰度和可维护性方面存在巨大差异,但如果单独查看它们可能并不明显,如下所示:

    // "LoadEntries" is (loosely) analogous to the "C" in MVC. 
    // What happens /inside/ LoadEntries is the Model, 
    // and button interaction is part of View functionality.  
    // MyList may also be viewable on screen as part of
    // the View.
    procedure TForm.Button1Click(Sender: TObject);
    begin
      MyDataModule.LoadEntriesIntoMyList(MyList); // LoadEntries is the "C" in MVC
    end;
    

    而不是

    // The "controller" is missing.  That omission of the essential 
    // decoupling mechanism between the model and the view will 
    // cost you or your company lots of money!
    procedure TForm.Button1Click(Sender: TObject);
    begin
      MyList.Clear;
      MyDataModule.qMyData.Open;
      while not MyDataModule.qMyData.Eof do
      begin
        NewItem := MyList.AddNewItem();
        NewItem.Blah := MyDataModule.qMyData.Fields['Field1'].Value;
        ...
        MyDataModule.qMyData.Next;
      end;
    end;
    

    我目前正在阅读 django 的书,他们的 MVC 设计确实令人印象深刻。特定于实现的模型、视图或控制器的任何部分都可以被不同的系统替换,而不会(显着)影响其他两个。毫无疑问,其他框架也有类似的方法,但我无法对此发表评论。

    【讨论】:

      【解决方案3】:

      恕我直言,模型-视图-控制器模式中的控制器部分通常是 delphi 应用程序的一种开销,因为此类应用程序基于事件的性质。模型和视图的分离就像在任何其他编程语言中一样。

      【讨论】:

        【解决方案4】:

        我切换到 C# 和 MVVM 模型 (WPF)。

        先看看 Embarcadero 的 Object-Oriented Design 论坛吧。

        您可以查看tiOpf,因为我看到他们有一些用于构建 GUI 的组件。 还有InstantObjects,不过不知道是不是还在开发中。

        VCL 组件的主要问题是它不支持绑定到对象/列表。因此解决方案是使用像EzSepcials 这样的虚拟数据集和数据感知组件,或者使用非数据感知组件并为各个组件编写中介。我应该提到Virtual TreeView

        【讨论】:

          【解决方案5】:

          我认为典型的 MVC 不适合 delphi 应用程序。我见过添加了太多样板代码的实现,这很可怕。与他们试图解决的问题相比,他们与自己的工作更多。

          我已经为 delphi 编写了一个 MVC 框架,但目前我只在我自己的项目中使用它。我还没有找到它的生产材料。它基于Model和Viewer,控制器只是两者之间的连接组织。

          模型包含或处理业务逻辑,查看器仅用于查看(GUI)。所以流程是这样的:

          1. 在视图中发生了一些事情(单击了按钮)。
          2. 视图向模型发送带有关联数据的命令
          3. 模型对业务数据进行更改并为视图准备新数据
          4. 使用新数据更新视图(仅视图的特定部分)

          我已经自动化了这个,所以当从视图中调用命令时,模型中相应的命令处理程序方法会被自动调用。当模型完成更改时,视图会更新。如果视图中存在与命令名称对应的方法,则调用该方法,否则调用通用的“UpdateView”方法。仅传递更改的数据,并且仅更新视图的相关部分。如果一个模型有多个视图,则全部更新。目前来回传递数据的媒介是 XML,因为它很灵活,因此传递任何类型的数据都没有问题。是的,在极端情况下性能可能会受到影响,但总体而言,这种方法似乎有效。我只需要清理它,这样就可以尽可能少地减少样板和开销。

          如果有兴趣,我可以在博客中介绍解决方案并对其进行清理以提高生产质量。

          【讨论】:

          • 博文总是令人感兴趣的。感谢您的简短版本
          【解决方案6】:

          我没有专门使用 MVC 或其他模式,但我今天所做的(当我使用 DB 感知控件进行数据同步时)就是以这种方式做某事:

          • 每个 entity 表单('entity' 以一种非常松散的方式,我指的是当用户点击菜单项或按钮时首先出现的表单)都有自己的数据模块及其数据组件。

            • 这些数据模块在运行时被初始化为应用程序连接(这是另一个数据模块 - 应用程序的全局),并且该初始化覆盖了设计时绑定到数据集的连接
            • 所有数据操作等都保留在数据模块中。该表单仅执行DM.SearchCustomers(&lt;conditions&gt;)DM.SaveData() 之类的操作。表单不执行 SQL,句号
            • Entity 表单封装了数据模块,因此主应用程序界面只需将连接传递给表单并将其重新发送给 DM。
              • 数据模块的创建/销毁由 entity 表单负责,因此通常使用表单作为所有者来创建 DM。
            • 在 90% 的情况下,数据源保持在表单中。

          我有一个标准的表单(和数据模块)层次结构,所以大多数时候简单的注册(如支付方式)表单都是用很少或没有代码的。

          Delphi 缺少(如上所述)对象的数据绑定,并且大多数控件要么是数据件,要么完全忽略它。

          【讨论】:

            【解决方案7】:

            我发现这方面有一些新举措。

            Stefan Glienke 在 2011 年 12 月写了一篇关于 MVVM 的 blog post 和一个名为 DSharp 的 delphi 库。

            现在看来它们是trying to implement 类似于 Delphi 的 Calibrun.Micro,这听起来很有趣。

            【讨论】:

              猜你喜欢
              • 2011-12-22
              • 2015-04-12
              • 2011-06-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-10-25
              • 2012-12-04
              • 1970-01-01
              相关资源
              最近更新 更多