我可以使用哪种设计模式来提供创建"pre-configured" UI 组件的几种方法



免责声明:我是Java编程的新手,通常使用"极限"OOP,所以这个问题的答案可能真的很简单。


我正在Vaadin中创建一个用户界面,Vaadin是一个Web应用程序框架,为我提供了许多有用的组件。通常,我对这些组件的默认设置不是很满意。

例如,如果我希望每个TextField组件在字段失去焦点时立即触发值更改事件。对于UploadField, TextArea, ComboBox等,我想在上设置这些类的每个实例的类似设置。

目前,我的文件是这样的:

public class ConfiguredComponents {
    public static TextField createConfiguredTextField(String caption) {
        TextField field = new TextField(caption);
        field.setImmediate(true);
        field.setSomeOtherOptions();
        ...
        return field;
    }
    public static UploadField createConfiguredUploadField(...) {
        ...
    }
    // etc. 
}

这一点都不像一个 !它只是静态方法的集合,这是我被告知要避免的。另外,我想把每个组件的逻辑放在一个单独的文件中。配置有时会很复杂,这样更有意义:这些都是非常小的自包含逻辑位。

以下是我考虑过的解决方案:

  • 保持简单:我可以去掉ConfiguredComponents,只制作一个包含小工厂类的大。例如,myproject.ui.components.TextFieldFactory知道如何创建已配置的TextField,仅此而已。

    优点:

    • 难看的ConfiguredComponents类不见了
  • 所有的逻辑都在单独的文件中。

缺点:

  • 没有单一的接口来创建我配置的组件;把它们放在一起的唯一原因是它们在同一个目录中。基本上,我必须公开很多小类,而且没有一个类或对象来管理它们。(直观地感觉这是一件非常糟糕的事情,但我不知道它是否真的是)
  • 也没有办法覆盖或扩展静态方法,所以"伪造"UI的东西测试变得更加困难。
  • 抽象工厂模式:我将ConfiguredComponents变成AbstractComponentFactory,管理许多较小的工厂。

    优点:

    • 所有的逻辑都在单独的文件中。
    • 实际配置组件的逻辑完全在幕后。
    • 缺点:

      • 我需要一个AbstractComponentFactory的实例,每次我想在代码的任何地方为我的视图创建一个组件。这意味着要么保持一个单例对象,这有很多缺点,要么每次创建一个new AbstractComponentFactory()

      • 如果我想在我的小"库"中添加新组件,我必须在两到三个地方编写新代码,而不仅仅是一个。

    • 其他一些我不知道的设计模式:我读过一些关于BuilderFacade的内容,感觉它们可能适用于这里,但是我不是很了解它们。

    • 你将如何处理这个设计决策?

      如果你的组件可以被继承,那就继续;对于要更改默认设置的每个组件,请创建一个新的派生类并在构造函数中配置settings。否则,

      抽象工厂模式是一个很好的选择。我认为你对这种模式有误解。AbstractComponentFactory只是一个接口,它不管理任何东西。这个接口看起来是这样的:
      interface AbstractComponentFactory {
          public TextField createTextFiled(...);
          public UploadField createUploadFiled(...);
          ...
      }
      

      在你的情况下,我认为你只需要一个工厂的实现:

      class MaurisComponentFactory implements AbstractComponentFactory {
          public TextField createTextFiled(...) {
              new ... config ... return;
          }
          public UploadField createUploadFiled(...) {
              new ... config ... return;
          }
          ...
      }
      

      正如你所说,我们既不应该使用Singleton,也不应该每次都创建新的MaurisComponentFactory。相反,我们应该在main()方法中只创建一个实例,然后尝试将该实例注入到需要创建组件的每个地方。

      我能想到的一种可能的方法是将abstractfactory与服务定位器或注册表模式一起使用

      因为你有无数的对象,没有复杂的实例化过程(如果有的话,求助于构建模式),你用抽象工厂创建对象,并在注册中心注册它们。无论你身在何处,都可以随时解决。

      或者您可以使用简单的IOC容器,其中整个应用程序都围绕

      进行包装。

      相关内容

      • 没有找到相关文章

      最新更新