首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >学生管理应用

学生管理应用
EN

Code Review用户
提问于 2013-05-11 10:05:07
回答 1查看 5.3K关注 0票数 7

我已经建立了一个基本的MVC项目,它是一个基于CSV文件作为数据存储的学生管理应用程序。每个用户都有一个特定的角色(学生、讲师、教授、学位项目负责人)。成功登录后,主窗口应该根据每个角色执行不同的操作。

如何在成功登录后隐藏登录视图,并根据每个用户的角色显示主窗口?

接口和抽象类呢?我能更好地概括/抽象代码吗?

对于不同的角色,我认为User是一个抽象类:

  • Student继承自User
  • Lecturer继承自User
  • ProfessorLeader来自Lecturer

ActionListener是在视图中还是在控制器中?

在主类中插入一个框架更好,还是每个视图应该从JFrame而不是JPanel扩展/继承?

到目前为止,对代码的一般反馈是非常欢迎的。

users.csv

代码语言:javascript
复制
user,password,role
user1,password1,student
user2,password2,professor

Studentenverwaltung.java

代码语言:javascript
复制
package com.studentenverwaltung;

import java.awt.EventQueue;

import javax.swing.JFrame;

import com.studentenverwaltung.controller.UserController;
import com.studentenverwaltung.model.User;
import com.studentenverwaltung.view.LoginPanel;

class Studentenverwaltung implements Runnable {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Studentenverwaltung());
    }

    @Override
    public void run() {
        User user = new User();
        LoginPanel loginPanel = new LoginPanel(user);
        UserController userController = new UserController(user, loginPanel);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(loginPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

}

UserController.java

代码语言:javascript
复制
package com.studentenverwaltung.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import com.studentenverwaltung.helpers.UserCredentials;
import com.studentenverwaltung.model.User;
import com.studentenverwaltung.persistence.FileUserDAO;
import com.studentenverwaltung.persistence.UserDAO;
import com.studentenverwaltung.view.LoginPanel;

public class UserController {
    private User user;
    private LoginPanel loginPanel;

    public UserController(User user, LoginPanel loginPanel) {
        this.user = user;
        this.loginPanel = loginPanel;

        this.loginPanel.login.addActionListener(new LoginListener());
    }

    class LoginListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String id = UserController.this.loginPanel.getId();
            String password = UserController.this.loginPanel.getPassword();

            if (LoginListener.this.authenticate(new UserCredentials(id,
                    password))) {
                // show main window based upon specific user role and hide login
                // window
                System.out.println("Successfully logged in...");
            }

        }

        private boolean authenticate(UserCredentials userCredentials) {
            UserDAO userDAO = new FileUserDAO("Files/users.csv");

            String id = userCredentials.getId();
            String password = userCredentials.getPassword();

            if (userDAO.getUser(id) != null
                    && userDAO.getUser(id).checkPassword(password)) {
                return true;
            }

            return false;
        }

    }

}

User.java

代码语言:javascript
复制
package com.studentenverwaltung.model;

import java.util.Observable;

public class User extends Observable {
    private String id;
    private String password;
    private String role;

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
        setChanged();
        notifyObservers();
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
        setChanged();
        notifyObservers();
    }

    public String getRole() {
        return this.role;
    }

    public void setRole(String role) {
        this.role = role;
        setChanged();
        notifyObservers();
    }

    public boolean checkPassword(String password) {
        return this.password.equals(password);
    }

}

LoginPanel.java

代码语言:javascript
复制
package com.studentenverwaltung.view;

import java.awt.GridLayout;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import com.studentenverwaltung.model.User;

public class LoginPanel extends JPanel {
    private static final long serialVersionUID = 1L;

    private User user;

    private JLabel idLbl;
    private JTextField idTxt;
    private JLabel pwdLbl;
    private JTextField pwdTxt;

    public JButton login;

    public LoginPanel(User user) {
        this.user = user;
        this.user.addObserver(new UserObserver());

        this.init();
    }

    private void init() {
        this.setLayout(new GridLayout(3, 1));

        this.idLbl = new JLabel("id");
        this.add(idLbl);

        this.idTxt = new JTextField(15);
        this.add(idTxt);

        this.pwdLbl = new JLabel("password");
        this.add(pwdLbl);

        this.pwdTxt = new JPasswordField(15);
        this.add(pwdTxt);

        this.login = new JButton("login");
        // login.addActionListener(new LoginListener());
        this.add(login);
    }

    public String getId() {
        return this.idTxt.getText();
    }

    public String getPassword() {
        return this.pwdTxt.getText();
    }

    private class UserObserver implements Observer {

        @Override
        public void update(Observable o, Object arg) {
            // TODO Auto-generated method stub

        }

    }

}
EN

回答 1

Code Review用户

回答已采纳

发布于 2014-03-06 21:35:26

  1. @tb-答的一个很好的评论:不要扩展JPanel,而是拥有一个私有的JPanel属性并处理它(封装)。对于处理JPanel实例的代码,不需要授予对所有UserPanel方法的访问权限。如果您进行扩展,您将被迫永远保持这种状态,如果封装,您可以随时更改,而不需要处理类之外的事务。我会让serialVersionUID场变得多余。
  2. 我以前从没听说过Observable。这可能不是巧合,Péter T r k对此的回答对其缺点有一个很好的解释:它们没有被使用,因为它们的设计有缺陷:它们不是类型安全的。您可以将实现Observer的任何对象附加到任何Observable上,这会导致一行中的细微错误。...
  3. 每个用户都有一个特定的角色(学生、讲师、教授、学位项目负责人)。我会使用复合(就像您使用role字段那样)。它更容易扩展(例如,教授也可能是领导者,或者领导者可能不是讲师)。检查有效的Java,第二版,第16项:如果您还没有读过,那么喜欢组合而不是继承。
  4. public LoginPanel(用户用户){ this.user = user;}如果User在这里是null,我会抛出一个异常。我想这是调用方的一个错误,没有必要继续使用无效状态的程序。无论如何,你迟早都会有例外的。立即抛出异常对调试有很大帮助,因为您可以得到包含错误客户端的帧的堆栈跟踪,而不仅仅是后面的NullPointerException,可能是来自另一个线程。(实用程序员:从熟练工人到大师,安德鲁亨特和大卫托马斯:死程序告诉不谎言。)
  5. 私有JLabel idLbl;私有JTextField idTxt;我不使用像这些字段名这样的缩写。它们使代码更难阅读,并破坏了自动完成。例如,如果键入idLa,自动完成将找不到任何东西。这常常很烦人。此外,它们很难发音。如果你不能发音,你就不能不像个白痴那样讨论它。“好吧,在这里的蜜蜂上,我们有一个小便,看见了吗?”这很重要,因为编程是一种社会活动。资料来源:RobertC.Martin的“清洁代码”,使用可发音的名称,p21
  6. this.idLbl =新JLabel("id");这里不需要this.。现代IDE使用突出显示将局部变量与实例变量分离开来。
  7. 如果(userDAO.getUser(id) != null &userDAO.getUser(Id).checkPassword(密码)){返回true;} User的局部变量在这里更容易阅读: User = userDAO.getUser(id);if (user != null &user.checkPassword(密码)){返回true};
  8. 我会将main方法移动到一个单独的类中。(例如,StudentAdministrationMain.)将类与其客户端分离通常是一个好主意。
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/26065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档