德尔福:视图的良好模式/策略< - >模型同步

时间:2009-10-13 21:57:27

标签: delphi design-patterns model view

现在有很多关于模型 - 视图 - 控制器,模型 - 视图 - 视图模型,模型 - 视图 - 演示器等的讨论。

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

你通常如何实施它?

7 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:6)

MVC的目的是解耦。解耦系统显然更容易维护,并且首先可以说更容易开发。您是否可以在不影响GUI代码的情况下从根本上改变数据库设计?您的GUI可以完全更改而不会对数据库设计造成太大影响吗?数据库中数据的一致性是否与GUI或基于表单的事件发生的顺序无关?这些是真正重要的问题,而MVC是一种积极回答这些问题的方法。

我不是专家,但过去我被这些事情所困扰:

  1. 尝试将所有显式引用放入数据模块内的数据库访问和数据库访问组件。如果你错误地站在太多的数据模块一边并不重要,但要注意不要在同一个数据模块中放置太多不相关的DB访问项(组合代码比分离代码容易得多)。

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

  3. 尽最大努力将尽可能少的业务逻辑放入组件事件中。这是不使用数据感知组件的自然扩展。很难保持这一点,因为这样做似乎就像做额外的工作一样,特别是在新项目中,你告诉自己你以后只会重构;当然,你知道这是谎言,因为以后永远不会来

  4. 第(3)点可能需要一个例子。以下两个片段之间在清晰度和可维护性方面存在巨大差异,但在单独查看它们时可能并不明显,如下所示:

    // "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设计确实令人印象深刻。特定于实现的模型,视图或控制器的任何部分都可以由不同的系统替换,而不会(显着地)影响其他两个系统。毫无疑问,其他框架也有类似的方法,但我无法评论这些方法。

答案 2 :(得分:2)

IMHO模型 - 视图 - 控制器模式中的控制器部分通常是delphi应用程序的开销,因为这些应用程序基于事件的性质。模型和视图的分离与任何其他编程语言一样。

答案 3 :(得分:1)

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

开玩笑说,先看看Embarcadero的Object-Oriented Design论坛。

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

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

答案 4 :(得分:0)

我认为典型的MVC不适合delphi应用程序。我已经看到实现增加了太多的样板代码,这是可怕的。他们与自己有更多的工作,他们遇到了他们试图解决的问题。

我为delphi编写了一个MVC框架,但是现在我只在我自己的项目中使用它。我还没有找到它的制作材料。它基于模型和查看器,控制器只是两者之间的连接组织。

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

  1. 在视图中发生了某些事情(单击按钮)。
  2. 视图将带有关联数据的命令发送到模型
  3. 模型更改业务数据并为视图准备新数据
  4. 使用新数据(仅视图的特定部分)更新视图
  5. 我已将其自动化,以便在从视图调用命令时,会自动调用模型中相应的命令处理程序方法。当模型完成更改时,视图会更新。如果在视图中存在与命令名对应的方法,则调用该方法,否则调用常规“UpdateView”方法。仅传递更改的数据,并且仅更新视图的相关部分。如果模型有多个视图,则全部更新。用于来回传递数据的媒介现在是XML,因为它很灵活,所以传递任何类型的数据都没有问题。是的,在极端情况下,性能可能会受到影响,但总的来说,这种方法似乎有效。我只需要清理它,以便尽可能少的样板和开销。

    如果有兴趣,我可以在博客上发布关于解决方案的信息并清理它以获得生产质量。

答案 5 :(得分:0)

我不使用专门的MVC或其他模式,但我今天所做的(当我使用数据库感知控件进行数据同步时)就是这样做:

  • 每个实体表单(非常松散的'实体',我引用的是当用户点击菜单或按钮时首先出现的表单将数据模块与数据组件一起使用。

    • 这些数据模块在运行时初始化为应用程序连接(这是另一个数据模块 - 应用程序的全局),初始化覆盖了设计时绑定到数据集的连接
    • 所有数据操作等都保留在数据模块中。表单仅执行DM.SearchCustomers(<conditions>)DM.SaveData()之类的操作。表单不执行SQL,期间
    • 实体表单封装了数据模块,因此主应用程序接口只是将连接传递给表单,然后将其重新发送到DM。
      • 数据模块创建/销毁是实体表单的责任,因此通常使用表单作为所有者创建DM。
    • 数据源在90%的情况下保留在表单中。

我有一个标准的表单(和数据模块)层次结构,所以大部分时间简单的寄存器(如付款方式)表单都是用很少或没有代码制作的。

Delphi缺乏(如上所述)对象的数据绑定,大多数控件都是数据件或完全忽略它。

答案 6 :(得分:0)

我看到这个领域有一些新举措。

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

对于Delphi来说,它们现在似乎是trying to implement类似于Calibrun.Micro的东西,听起来非常有趣。