GUI Architectures

进化历史

Forms and Controls

  1. 开发者使用通用控件在form中完成App特有逻辑
  2. form描述了控件的布局
  3. form观察控件,通过处理方法来回应感兴趣的事件
  4. 简单的数据编辑使用数据绑定来完成
  5. 复杂的变化使用form的事件处理方法来完成

MVC

  1. 明确的分开表现层(view&controller)和领域层(model)- Separated Presentation
  2. 把 GUI widgets 分成 controller(用来处理用户输入) 和 view (用来展示model的状态)。Controller 和 view不应该(大部分情况下)直接的通信而是通过model。
  3. 让views(and controller)观察model 以便允许多个widget都可以更新而不需要直接通信 - Observer Synchronization。

Model-View-Controller 是一种把应用分离成领域、呈现、和用户输入的几种模块的方法。

MVC Misconceptions

一个常见的误解是Model-View-Controller三个模块之间的关系是Controller用来分离View和Model。尽管MVC模式确实分离了应用领域层和表现层,但是这是通过观察者模式完成的,而不是Controller。Controller是用户和应用之间的中介,而不是用来分离View和Model的。

Application Model

  1. 遵从MVC,使用了 Separated Presentation 和 Observer Synchronization 模式。
  2. 引入了中间的应用模型(ApplicatonModel) 来处理表现逻辑和状态 - 是Presentation Model 的一部分。
  3. UI组件不再直接观察领域模型,而是观察应用模型。
  4. 大量使用属性对象来连接不同的层并通过观察者模式来实现细粒度的数据同步
  5. 在应用模型中操作UI组件并不是应用模型原有的设计,但是在复杂的情况下,这种使用非常普遍。

MVP

对比

  1. Form And Controls:MVP有底层model,Presenter会通过Observer Synchronization 模式操作model来更新view。尽管可以直接访问widget,但是这并不能成为除了使用model来更新之外的首选。
  2. MVC:MVP使用一个Supervising Controller来操作model。Widgets会把用户操作转交给 Supervising Controller。Widget没有被分成 view和controllers。你可以把 Presenter看成是没有处理原始用户手势功能的controller。另外非常重要的是 presenter 是处在 form 层级的而不是 widget层级的,这是和MVC中Controller一个更大的不同。
  3. ApplicationModel:views把事件转交给presenter这和ApplicationModel类似。但是view可以直接通过Model更新,presenter并不是Presentation Model的角色。另外,在不方面使用Observer Synchronization模式的行为中,presenter默认是可以直接访问widgets的。

  4. 用户手势(译注:现在认为应该译成动作)通过 widgets 被转移到 Supervising Controller

  5. presenter 协调 domain model 中得变化
  6. MVP的不同版本处理view的方式不同。从Observer Synchronization 到使用 presenter 来实现所有的更新。

Humble View

The Humble Dialog Box论文中使用了MVP模式,但是比原始的MVP模式更进一层。presenter不仅仅处理用户输入,同时负责数据填充,这样,widget不在需要知道model。它形成了被 presenter操作的 Passive View。

这不是唯一的使UI变得简单的方式。另外一种方式就是使用 Presentation Model,尽管这样还是需要在widget中做一些逻辑,但是对于widget来说已经足够把自己映射到 Presentation Model 了。

这两种方式的关键是测试presenter或者测试presenter model,你可以在不碰那些难以测试的widget之前测试到大部分的UI问题。

使用 Presentation Model 模式可以把大量真实的逻辑放在 Presentation Model 里面。所有的用户输入和现实逻辑都路由到 Presentation Model,这样所有的widget需要做的就是把自己映射到 Presentation Model 的属性上。然后你就可以测试Presentation Model 的大部分逻辑而不需要现实任何界面 - 唯一的风险存在于 widget映射。但是这些操作很简单可以不测。在这个例子中屏幕还是没有使用 Passive View 来的简单,但是区别也很小了。

因为 Passive View 使 widgets变得太简单了,甚至不存在映射,Passive View 甚至消除了 Presentation Model 模式中存在的风险。代价是你需要一个 Test Double 框架来模拟屏幕 - 这是你需要额外构建的机制。

在Supervising Controller模式中也存在这种折衷。让每个view做简单的映射会引入风险(和Presentation Model类似)但是带来的好处是可以简单明确的声明映射。在 Supervising Controller 中映射会比较少,因为在 Presentation Model 中还要处理复杂的更新问题。而 Supervising Controller 只要在内部操作widget就行了而不需要映射回去。

REF

GUI Architectures
UI 架构小史1(GUI Architectures) - 简书