0

我有一个需要重构的项目。它是一个 Java 桌面 SWT/JFace 应用程序,具有大约 40 个 GUI 组件,主要组件控制次要组件的生命周期。我想拥有低耦合的良好模块化设计,但是如果没有很长的构造函数,我找不到避免全局状态的方法。

例如,当前软件国际化的方法是这样的:

public class Main {
    public static void main(String[] args) {
        MyMessages.loadMessages();
    }
}
public class MyMessages {
    private static ResourceBundle messages;
    public static void loadMessages() {
        messagesBundle = ResourceBundle.getBundle("messages", "en");
    }

    public static void getMessage(String m) {
        return messagesBundle.getString(m);
    }
}

public class SomeComponent extends Component() {
    public void init() {
        String textboxLabel = MyMessages.getMessage("someMessage");
    }
}

代码中的其他地方使用单例(用于数据模型),这使得随着代码库的增长很难分析依赖关系。

另一种方法是使MyMessages有状态的并通过 GUI 组件的层次结构一直传递它的实例。对我来说,与感知到的好处相比,这似乎很混乱,容易出错并且不值得麻烦。

还有什么其他方法可以设计成这样:

  • 不依赖于本质上是全局变量。
  • 使依赖关系明确。
  • 不会用冗长的构造函数弄乱代码。

我应该考虑依赖注入框架,还是有另一种对小型桌面应用程序来说似乎并不过分的方法?

4

3 回答 3

2

我应该考虑依赖注入框架,还是有另一种对小型桌面应用程序来说似乎并不过分的方法?

对于小型桌面应用程序,我建议使用依赖注入设计模式,但不要使用工业强度的 DI 框架。

在您的代码中,消息帮助程序类是可以的,但是您的 SomeComponent 类绝对不是 DI 友好的:

public class SomeComponent extends Component() {
    public void init() {
        String textboxLabel = MyMessages.getMessage("someMessage");
    }
}

SomeComponent 现在绑定到 MyMessages。

而是使用类似的东西:

public class SomeComponent extends Component() {

    public void setTextBoxLabel(String value) {
        // implementation depends on requirements
    }

    public void init() {
        // do something with all the properties that were set
    }
}

基本上只需将设置器添加到您的组件。这是 DI 的第一部分。让你的所有类都是松散耦合的,每个类都相信有人会负责设置它的所有属性。不需要全局状态,因为组件所需的一切都将被注入其中。

当然,一旦您这样做了,您的启动代码将成为一场噩梦,因为您必须创建所有这些对象并设置它们的所有属性,并且它们都与您的应用程序相关联。此时您开始重构您的启动代码并创建负责为您创建对象的构建器和/或工厂。

假设其中一个组件由属性文件初始化。您创建一个构建器来读取属性文件、实例化组件、设置组件属性并返回实例。该组件对属性文件一无所知。它只是有一些它知道将在启动时设置的 getter 和 setter。

稍后您决定使用 XML 作为文件格式 - 但对于不同的应用程序,同时仍将属性文件用于第一个应用程序。没问题 - 创建一个读取 XML 文件并构建组件的新 XML 构建器 - 但实际的 GUI 组件保持不变,因为它与初始化的方式完全分离。

关键是审查创建设计模式并找出哪些模式(构建器、工厂等)可以帮助您可靠地创建组件,同时避免全局状态。

于 2012-11-13T02:44:30.873 回答
1

我会使用全局状态。特别是如果您正在重用视图。恕我直言,对将在整个应用程序中大量使用的各种组件进行某种查找并没有错。

请注意,如果您使用 DI 框架,那么可能会隐式使用某种全局状态(当然,这是依赖于 DI 框架的实现)。以 Spring 为例,ApplicationContext 是一个全局对象,它本身将保留各种组件和/或管理组件的生命周期,具体取决于各种 bean 的配置。

拥有全局组件不一定是坏事。如果权衡是巨大的构造函数签名和传递引用,我会随时使用全局引用(我会把它们放在某种Application对象中)。

于 2012-11-13T01:02:42.490 回答
0

使用 java logger api 怎么样...此外 StreamHandler 类可以扩展并将输出流设置为组件。您还可以跟踪消息和相关的类和方法。

于 2012-11-13T01:05:15.463 回答