组织模型方法调用控制器的正确方法

时间:2017-04-24 19:49:15

标签: java model-view-controller javafx login javafx-8

我使用登录页面实现javafx应用程序,并为不同用户的角色提供了几个页面。

用户识别是在Login.java类中实现的,该类应该被称为模型。 但是用户的字符串登录名和密码出现在LoginController.java文件中的页面元素中。所以现在我在控制器中提交了表单提交事件处理程序:

public class LoginController {
    @FXML private TextField loginField;
    @FXML private TextField passwordField;
    @FXML private Button loginButton;
    @FXML private Text messageText;

    @FXML
    protected void submitLoginForm(ActionEvent event) {
        if (!Login.getInstance().authorise(loginField.getText(), passwordField.getText())) {
            messageText.setText("Invalid credentials.");
        }
    }

这就是我在登录中所拥有的:

public class Login {
    private Scene scene;
    private User loggedUser;
    private static Login instance;

    public Login(Scene scene) {
        this.scene = scene;
        instance = this;
    }

    public static Login getInstance() {
        return instance;
    }

    public boolean authorise(String userId, String password) {
        loggedUser = User.recognize(userId, password);
        if (loggedUser.equals(User.UNAUTHORISED)) {
            return false;
        }
        goToInfoScreen();
        return true;
    }

User.recognize()只返回特定用户,该用户保存在上面的Login类中:

public static User recognize(String l, String p) {
        return Arrays.stream(values())
                .filter(user ->
                        user.login.equals(cryptWithMD5(l.toLowerCase().trim()))
                        &&
                        user.pass.equals(cryptWithMD5(p)))
                .findFirst().orElse(UNAUTHORISED);
    }

这样可行,但我不得不从控制器调用每个模型的静态实例。更重要的是,我有getInstance()方法以及公共构造函数。这对我来说很奇怪。

同样的情况是注销方法。我在Login模型类中有这个逻辑:

public void logout(){
    loggedUser = null;
    goToLoginScreen();
}

使用静态实例从控制器调用它:

@FXML protected void processLogout(ActionEvent event) {
        Login.getInstance().logout();
    }

在start()方法中,我创建了一个模型Login实例:

 @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(new StackPane(),  800, 600);
        Login loginManager = new Login(scene);
        loginManager.goToLoginScreen();

我的问题是: 从控制器调用模型实例似乎真的好吗?或者解决这种情况的最佳做法是什么? (也许将模型实例作为控制器的构造函数参数发送?然后在start()方法中只调用控制器的方法?)

还有一点:在我的登录模型中,我识别出一个用户角色,需要根据他的角色在下一个屏幕上隐藏或显示一些元素。

所以我可能需要在我的模型中获得所需的屏幕控制器并使用这样的setter将用户发送给它?

       InfoPageController controller = loader.getController();
       controller.setLoggedUser(loggedUser);

然后在InfoPageController中说出类似

的内容
if (loggedUser.equals(User.ADMIN)) advancedTabPane.setVisible(true);

再说一遍:这是否可以,或者还有另一种正确的方法来调整已登录用户的界面?

0 个答案:

没有答案