两种加载FXML的方法; 为什么一个优先于另一个?

Zep*_*hyr 1 java javafx fxml

我正在寻找关于为什么我们应该使用一种方法而不是加载和显示新的FXML阶段的反馈.

大多数时候,我看到教程和类似的东西显示从一个单独的类完成一个阶段的加载.但是,它也可以在FXML文件的控制器本身内完成,我个人认为这样做更清洁,更易于管理.

请考虑以下Main.java类:

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception {

        // Method 1:
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout.fxml"));
            loader.setController(new LayoutController());

            stage.setScene(new Scene(loader.load()));
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

这似乎是流行的方法.它创建控制器并设置Scene然后显示它.

但是,如果我们将start()方法改为:

@Override
public void start(Stage stage) throws Exception {

    LayoutController controller = new LayoutController();
    controller.showStage();

}
Run Code Online (Sandbox Code Playgroud)

并将FXML加载代码移动到LayoutController构造函数中,结果是一样的:

public class LayoutController {

    @FXML
    private Label label;

    private Stage stage = new Stage();

    public LayoutController() {

        // Method 2:
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout.fxml"));
            loader.setController(this);

            stage.setScene(new Scene(loader.load()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void showStage() {
        this.stage.showAndWait();
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里看到的好处是视图和逻辑之间的分离更多.关于LayoutController它及其相关FXML文件的所有内容都包含在一个地方.

所以我的问题是:第二种方法有什么问题?我假设它不是标准方法的原因,但我不能看到任何缺点.

像这样的问题会更适合Code Review吗?我并不是真的在征求意见,因为似乎有一个通用的"规则",即使用第一种方法.

fab*_*ian 5

在这种情况下没有太大的区别.

对于较大的程序,第二种方法是不可取的:

它违反了单一责任原则:

该班负责:

  • 创建场景
  • 创造舞台
  • 显示阶段(更糟糕的是,它以可能干扰其他逻辑的方式执行此操作(showAndWait))
  • 它是视图的控制器,可能负责处理多个事件

此外,类的设计方式可以防止责任被移动到其他类而没有问题.

在较大的程序中,您可能希望创建一个类来管理将数据传递到视图,排列窗口或将视图显示为场景的一部分等.第二种方法不适合这种情况.

此外,如果不重复自己,也会变得更难.除非将逻辑移动到公共超类型,否则还需要实现用于在每个控制器类中显示场景的逻辑.重复相同或类似的代码会导致难以维护的代码.


注意:使用单个类来加载fxml并用作控制器不一定是坏事,但您应该使用FXML简介中提供的自定义组件方法.