我已经看到过这个“设计模式”(不知道还有什么叫它..模板?)在Java代码中不止一次出现。预计申请将被延长并包括主要方法。我无法弄清楚在start方法中使用Class而不是AppFrame有什么好处,因为它只是类型转换为AppFrame的类型。这一切似乎都是毫无意义的,也许有人可以填补我。
public class Application {
public static class AppPanel extends JPanel {
//stuff
}
public static class AppFrame extends JFrame {
protected AppPanel mainPanel;
//more stuff
}
public static AppFrame start(Class appFrame) {
try {
final AppFrame frame = (AppFrame) appFrame.newInstance();
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
frame.setVisible(true);
}
});
return frame;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args){
Application.start(AppFrame.class);
}
}
答案 0 :(得分:2)
我也见过这种情况,特别是在相当陈旧的例子中。
这个想法似乎是一切都以一个静态调用开始,用户不会在堆上创建任何东西。相反,“应用程序框架”以某种方式实例化它所需要的内容,并且用户仅指示要使用的具体实现。因此,用户指示要使用的类,但实际上还没有实例化。执行此操作的一个风险是您可以将其实例不可转换的类转移到AppFrame。这可能会导致异常。
我个人认为这个丑陋的设计。在通过类对象(如Smalltalk或Python)直接实例化类更常见的语言中,它是有意义的。在Java中,我认为坚持使用工厂接口更加笨拙而且更加OO。
答案 1 :(得分:2)
该模式称为type token
,由Gilad Bracha创造并在Class Literals as Runtime-Type Tokens中讨论,以及mentioned here。实例化顶级容器JFrame
是一种有趣的方法,但GUI组件应该在Event Dispatch Thread(EDT)上构建。根据构造函数中的//stuff
以及start()
的调用方式,它可以减轻escaped this的影响。
答案 2 :(得分:1)
start()的签名允许传递任何类,但实现将其限制为AppFrame的子节点,后者只是嵌套的静态类。由于所有内容都堆放在同一个文件中,我不知道为什么所有这些都是必要的,我同意 - 在这个特定的例子中实现它的方式毫无意义。