Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
User interface GUI模式问题:PropertyChangeListener与专用视图界面_User Interface_Language Agnostic_Design Patterns - Fatal编程技术网

User interface GUI模式问题:PropertyChangeListener与专用视图界面

User interface GUI模式问题:PropertyChangeListener与专用视图界面,user-interface,language-agnostic,design-patterns,User Interface,Language Agnostic,Design Patterns,我想通过接口将模型与其视图配对。我想控制视图更新的时间和频率。因此,PropertyChangeListener之类的东西不会很好地工作(在每个属性设置后都会触发一个事件) 我不是为特定的GUI框架开发的。这里的目标是能够交换不同的GUI前端(目前用于测试,但稍后可能对不同版本的应用程序有用)。它们可能是Swing,也可能是web浏览器(例如,通过GWT) 下面是我的方法。视图实现了一个接口,以提供要更新的方法。当控制器确定已完成模型更新时,会触发此操作。这对我来说仍然没有问题,因为控制器仅通过

我想通过接口将模型与其视图配对。我想控制视图更新的时间和频率。因此,PropertyChangeListener之类的东西不会很好地工作(在每个属性设置后都会触发一个事件)

我不是为特定的GUI框架开发的。这里的目标是能够交换不同的GUI前端(目前用于测试,但稍后可能对不同版本的应用程序有用)。它们可能是Swing,也可能是web浏览器(例如,通过GWT)

下面是我的方法。视图实现了一个接口,以提供要更新的方法。当控制器确定已完成模型更新时,会触发此操作。这对我来说仍然没有问题,因为控制器仅通过模型与视图交互,控制器不依赖于视图的特定实现

所以,我想我的问题是

  • 这个效果好吗
  • 这是标准做法吗
  • 这个图案有名字吗
粗略代码示例(Java):


我将避免强制视图实现仅用于更改通知的接口。改为在模型上创建单独的“立即更新”事件。

模型不应直接控制或了解视图。视图应该向控制器注册回调,以便控制器可以告诉视图何时更新,这就是为什么它是控制器的原因。您可以让模型允许modelChangedEvent的外部侦听器。然后,视图可以在这方面注册到模型中,而模型不知道存在视图。请参阅J2EE for MVC以及如何在模型中存在状态更改的间接事件通知。

对于在计算机桌面上运行的传统应用程序,我建议使用。负责创建和管理表单的类是一个薄壳,它将事件传递给UI对象。UI_对象通过接口与表单交互。在术语中,UI对象实现一个UI_视图接口,并向位于对象层次结构较低位置的视图控制器注册自身

然后,UI_对象执行实现修改模型的对象。命令对象可以通过视图控件公开的接口与各种视图交互

这样做的目的是允许您剥离表单类,并用实现表单接口的存根类替换它们。存根类用于自动化测试,特别是集成测试

接口精确地定义了表单、UI_对象、命令和视图之间的交互。它们可以被设计成相对不懂语言的,这样就可以更容易地在平台之间进行移植

示例中缺少的是命令对象。你需要这个结构

  • ItemViewForms
  • ItemViewImplementation
  • ItemViewFormInterface
  • ItemView命令
  • ItemViewInterface
  • 我的模型
将ItemList合并到ItemViewImplementation中

ItemComponent将使用ItemViewInterface向ItemViewImplementation注册

事件的顺序看起来像这样

  • 用户希望更新该项
  • 单击用户界面(假设用户界面 包括用鼠标点击)
  • 表格告诉我们 ItemView通过 已安装X的ItemViewInterface 使用Y参数完成
  • 然后是ItemViewImplementation 使用 它需要来自Y的参数
  • 命令对象采用Y 参数会修改模型和参数 然后告诉
  • ItemView通过 ItemViewInterface以更新UI
  • ItemViewImplementation告诉 ItemViewForms以更新UI 通过ItemViewFormInterface
  • ItemViewForms将更新
这种方法的优点是每个层的交互都是通过接口精确定义的。软件操作将本地化到命令对象中。表单层的重点是显示结果。视图层负责在命令和窗体之间路由操作和响应。命令是修改模型的唯一工具。此外,您还可以剥离表单实现来替换任何您想要的UI,包括模拟对象,以进行单元测试

// Controller, manages Items (the model)
class ItemList {

   void addItem(Item item) {
   }

   void doStuffWithItems() {

     // perform some set of operations, such as sorting or layout
     for (Item item : items) {
       // ....
     }

     // now with everything in it's final position:
     for (Item item : items) {
       item.updateView();
     }
   }
}

// Model
class Item {
  private int top;
  private int left;
  private int width;
  private int height;

  // Can remember it's previous position/size:
  public void savePostion() {
  }

  // And recall it for the Controller to use:
  public public Position getSavedPosition() {
  }

  // Plus some other useful functions:
  public boolean intersectsWith(Item other) {

  }

  public void updateView() {
    this.view.update();
  }

  void setView(ItemView view) {
    this.view = view;
  } 
}

// Interface used by View implementations
public interface ItemView {
  // Trigger the view to reflect the current state of the model
  void update();
}

// Example, as a Swing component
class ItemComponent extends JComponent implements ItemView {
  private Item item;

  public ItemComponent(Item item) {
    this.item = item;
    item.setView(this);
  }

  // ItemView#update
  public void update() {
    // update the component's size/position
    setBounds(new Rectangle(item.getLeft(), item.getTop(), item.getWidth(), item.getHeight()));
  }

  @Override
  public void paint(Graphics g) {
    // ...
  }
}