【问题标题】:conditional import有条件导入
【发布时间】:2013-02-08 15:06:44
【问题描述】:

我正在考虑将 dbus 功能添加到使用 swing 的 java 程序中,以便可以使用脚本来执行某些功能。 这个东西也必须在没有 dbus 的 windows 上运行。

所以我正在考虑做以下事情:

dbus.java:

import dbus; //Whatever the module is called
class dbus implements some_interface {
    //blah blah
}

dbus_fake.java

class dbus_fake implements some_interface {
    //full of empty methods
}

dbus_manager.java

class dbus_manager {
    static some_interface get_dbus() {
        try {
            return new dbus(); //This should fail when loading the class, because the imports are not satisfied.
        } except {
            return new fake_dbus();
        }
    }
}

你认为这是个好主意吗?它会起作用吗?有没有更好的方法?

【问题讨论】:

  • 如果你把它放在单独的罐子里,它肯定会起作用。一个用于您的应用程序,包含接口。每个不同平台都有一个罐子。只需将平台的 jar 放入类路径中即可。
  • 如果你的项目非常大,你可能想看看像 Spring 这样的依赖注入框架。他们使用属性文件来管理哪些特定的接口实现实际上被注入到您的代码中。然后,您可以为每个操作系统拥有单独的属性文件。

标签: java import


【解决方案1】:

不幸的是,依靠构造函数抛出ClassNotFoundExceptions 有点不可靠(尽管它现在可能适用于您的用例)。

我会使用 Class.forName 加载类以获得更可靠的行为(同时使用更多 Java 风格的名称;):

class DBusManager {
    static SomeInterface getDBus() {
        try {
            return Class.forName("your.pkg.RealDBus")
                        .getConstructor()
                        .newInstance();
        } catch(ClassNotFoundException e) {
            return new FakeDBus();
        }
    }
}

【讨论】:

  • 我懒得想伪代码的好名字。也许反思是个好主意。
【解决方案2】:

为什么这么难?只需为每个平台维护一个单独的 jar 文件。它使依赖关系变得更好,易于单独维护,扩展新实现等......

windows-dbus.jar
 |
 +- class DBus implements SomeInterface { fake code }


linux-dbus.jar
 |
 +- class DBus implements SomeInterface { real dbus code }

根据您所在的平台,在类路径中包含适当的 jar。并在程序中请求一个新的 DBus 实例。

final SomeInterface bus = new DBus();

如果您的程序与 WebStart 一起分发,您甚至可以提及哪个 jar 用于哪个平台。

【讨论】:

  • 部署多个 jar 文件简直是地狱,除了记录的运行方式是使用 ant。
  • 这当然是个人喜好问题。 :-) 但是您可以使用 ant 轻松构建依赖于操作系统的类路径:stackoverflow.com/questions/453170/…
猜你喜欢
  • 2021-05-17
  • 2011-03-08
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2014-09-04
  • 2012-07-02
  • 1970-01-01
  • 2021-09-02
相关资源
最近更新 更多