Skip to content

Latest commit

 

History

History
235 lines (155 loc) · 13.1 KB

简述java实验设计的实践过程(持续更新).md

File metadata and controls

235 lines (155 loc) · 13.1 KB

简述Java实验设计的实践过程(持续更新)

本来,这次实验应该写一个实验报告,描述在实验过程当中遇到的一些问题和解决方案。不过最近有很多同学都在纠结这次实验应该从哪下手,我从一个Java新手的角度帮大家理清一下思路,就当做是实验报告了。(注:由于Java水平有限,下文中的很多习惯用词可能来自Objective-C语言。)

我的设计模式灵感来源于著名的MVC模式,有兴趣的同学可以百度一下。

具体代码可以参见GitHub

一、基本结构

说是学生管理系统,就应该可以预见到,主界面应该是一个有管理功能的表格,按照常理,我们可以添加/修改/删除学生的信息。同时,一个功能完备的系统一定不是随意进入的,所以我们还需要登录模块。登录模块一般包括登陆/注册/忘记密码三部分,这三部分的注册和忘记密码在样式上基本相同,都是用户名占一行,密码和确认密码占两行。

构思好基本的界面之后,我们很有必要把它画下来,方便我们在写代码的时候理清层次。

二、数据模块
1.学生

数据模块的搭建是贯穿整个项目的。第一次的搭建很可能和项目完成的时候相差甚远。我一开始搭建数据模块的时候,自以为方法已经给的尽可能的全,但是标记第一个release的时候,和最初相比多了一倍的代码量。这里,我们强调的是代码在实现某些功能的时候,需要根据需求不断地更新基础需求。

由于我们在管理的是学生的信息,所以一开始需要写学生类。学生类应该包含一些简单的属性,你也可以根据需要在后期添加,同时写好所有属性的get/set方法,一定要注意类型。

到这里,看看表,过去了2分钟。在这2分钟里,你完成了这个项目的第一步,同时也是最关键的一步——学生类都搭建好了,管理学生还不简单吗?

但是,如果你管理的只是三四个学生,就像导师带研究生一样,你还可以简单地实例化三四个学生对象就可以了,非常可惜的是,学生管理经常出现大数据——如果你是班主任,你要管五六十个学生,你要是辅导员,就得管几百个学生。一个个实例化显然是不现实的。所以,我们可以选择构建一个线性链表管理学生。

阅读笔记:线性链表是一种具有连接存储结构的线性表。相邻的元素在逻辑和存储地址上可能都并不是相邻的。简单地说,它就是线性结构的“链表”。

读懂上面的内容,就相当于为你在数据结构的学习上做了一点点预习。当然,数据结构并不是这么简单的,线性结构(linear structure)是其中不那么抽象的一部分。考虑到我们管理学生的时候一般并不考虑学生之间的关系,只是在序上有所区别,按序排列,所以学生可以添加到一个线性列表里。

2.学生列表

现在,整个项目最复杂的类之一即将开始——你的好友【学生列表】上线了。

学生列表是在项目中的主体功能中最重要的一环。幸好,Java在表面上并没有C语言那么复杂的指针,线性链表其实只是一个泛型的数组。如果你的记忆力还好,就会想起实验三中有一个重要的类叫ArrayList,就是你了。

学生列表的类里,方法会有很多。比如添加/修改/删除某个学生,甚至是某几个学生。获取学生的列表,查找列表当中的某个学生等等。需要注意的是,一定要为每个方法都取一个容易识别的名字,名字不怕长,只怕你以后再也看不懂了。比如添加学生的方法,添加某个学生你可能会写成addStudent(ZHRMoeStudent),那么添加很多学生应该取什么名字呢?好的方法是,添加一个学生的时候,方法名就说好添加一个学生,例如addSingleStudent(ZHRMoeStudent)。(这里的ZHRMoeStudent只是我假设的学生类的名字)

当你用正常的方法声明学生列表的实例时,依然会像上次一样收到一个提示,泛型的具体类型并没有声明。这次,我们不再使用屏蔽的措施,而是正面地解决它。我们可以用如下的方式声明一个学生列表实例。

public ArrayList<ZHRMoeStudent> studentList = new ArrayList<ZHRMoeStudent>();

如果你只用了3分钟就写好了这个类,我首先要恭喜你有一个飞快的手速,但同时,我也建议你再仔细地想想有没有什么可以添加的方法,免得以后添加的时候打乱编程思路。

3.用户

登陆的时候,你想判断用户名密码是否正确,应该去找谁呢?答案就是User类。所谓的用户其实就是用这个用户系统的人,他们的属性就是用户名、密码。写好他们对应的get/set方法,看看表,2分钟。

4.用户列表

注册?忘记密码?如果你想更改用户的信息,要是只实例化了几个用户的对象,肯定是说不过去的。这样的话,我们就应该再给用户建立一个列表。方法和学生的列表类似,都是删除/添加等等。这个过程大概需要5分钟的时间

5.小结

理论上讲,数据模块的搭建只需要15分钟。虽然你之后肯定还需要再雕琢这一部分的方法,而且这种修改一定是贯穿整个项目周期始终的。但是,迈出了这重要的第一步,意义是非常重大的。还需要额外说明的是,学生列表和用户列表的两个列表属性一定是静态的,不要问我静静是谁。

三、登陆模块
1.登陆界面

终于可以画界面了!

为了让你可以更加自由地描绘界面结构,我只提供一些简单的思路。

在画界面之前,一定先在哪里画出这个界面的具体样子,这对你了解这个界面的结构和排列有非常大的帮助。然后,分区域把对应的元素规划成JPanel类的对象。

由于,登陆界面这个类是一个图形界面,所以它应该继承于JFrame

需要注意的是,密码框并不是简单的JTextField,而是JPasswordField,这种框当中的文字都会(在表面上)加密成点。

可能用到的界面元素类:

  • 区块 JPanel

  • 文字 JLabel

  • 按钮 JButton

  • 输入框 JTextField

  • 密码框 JPasswordField

同时,界面上的按钮在点击的时候应该做出反应,这时候,我们应该为每一个按钮都添加事件监听,监听的是这个界面本身。所以相应的语句应该是someButton.addActionListener(this)

然后就报错了。

因为,这个界面本身并不是一个动作的监听者,它只是一个界面而已。所以,我们让它实现ActionListener这个接口。相应的类定义是:

public class ZHRMoeLogin extends JFrame implements ActionListener{
	//这个界面的代码
}

报错变成了提示,这个提示告诉我们,接口的方法我们还没有实现。所以接下来,我们要给这些按钮实现动作事件。

public void actionPerformed(ActionEvent a) {
	if(a.getSource() == someButton) {
		//写关于这个的按钮按下时的代码
	} else if(a.getSource() == anotherButton) {
		//写关于另一个按钮按下时的代码
	}
}

需要解释的是,ActionEvent是一个动作事件,其实也就是点击了这个界面的某个元素,根据点击不同的按钮,我们可以做出不同的反应。

另一个问题是,用户名和密码需要和之前的某个具体的用户相同,这里我不详细介绍对照的方法,不过搜索一定是一个不错的选择。另外,用户名和密码为空的时候,登陆应该被阻止(一开始,我故意留下了这个漏洞方便其他界面的检查,所以是否在一开始就解决这个问题,依情况而定)。这其中的逻辑,你们可以用离散数学的分析方法做分析(顿时就高大上了)。

2.注册界面

注册需要对用户的列表进行添加操作,这里就要看你给用户列表写的方法是否详尽了。

同时,注册新用户的时候,需要输入两遍密码防止用户手残。两次密码需要对照一致才能注册,而用户名不可以是已经注册了的用户名,也要做相应的检查。这其中的逻辑,也应该细致地考虑。

3.忘记密码界面

忘记密码界面其实就是修改密码的界面。这个界面的结构和注册界面大体相似,但是不同在于,只有用户名已经存在的时候才能更改密码(即逻辑与注册界面相反)。而用户列表内的操作,可以选择先删除原来的用户,然后把用户名和新的密码重新生成一个用户加入列表当中。

四、主界面
1.主界面概述

为了让我们写出的主界面美观,代码应该下一番功夫认真排版。

主要的数据都填在了一张JTable的对象(也就是一张表)里,这张表由于需要滚动,所以要加入JScrollPane,即滚动的模块当中。

JTable数据的获取,需要通过setModel方法设置。

studentListTable.setModel(new TableModel() {
            @Override
            public int getRowCount() {
                return ...;
                //这里需要返回列表的行数
            }

            @Override
            public int getColumnCount() {
                return ...;
                //这里需要返回列表的列数
            }

            @Override
            public String getColumnName(int columnIndex) {
                return new String[]{"", "", ...}[columnIndex];
                //这里需要返回列标题的序列
            }

            @Override
            public Class<?> getColumnClass(int columnIndex) {
                return String.class;
                //这里需要返回类型
            }

            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return true;
                //这里返回的是列表的内容是否可以修改,这里设置为是,就可以完成学生信息的修改了
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                ZHRMoeStudent s = studentArray.getSingleStudent(rowIndex);
                return new Object[]{...}[columnIndex];
                //这里返回学生信息,填满列表 需要填写get方法
            }

            @Override
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
                ZHRMoeStudent s = studentArray.getSingleStudent(rowIndex);
                switch (columnIndex) {
                    case 0:
                        ... //填写第0列的set方法,以下依此类推
                        break;
                    case 1:
                        ...
                        break;
                    case 2:
                        ...
                        break;
                    case 3:
                        ...
                        break;
                    case 4:
                        ...
                        break;
                    case 5:
                        ...
                    default:
                        break;
                }
                //修改列表元素
            }

            @Override
            public void addTableModelListener(TableModelListener l) {
            	//重写方法
            }

            @Override
            public void removeTableModelListener(TableModelListener l) {
				//重写方法
            }
        });

通过这些代码,列表就能够得到数据了。

2.添加学生界面

添加学生的界面应该是可以获取学生的所有属性的。注意,有些属性例如“性别”,让用户去输入显然是可能出现“手残”的情况的。为了避免这种笑话的发生,我们可以添加两个JRadioButton分别表示男女,然后把两个选项放进一个ButtonGroup里,使得这两个选项只能单选。

这两个JRadioButton也应该是动作的监听者,用来设置性别的男女。

3.总结

图形界面是不是不好画啊,是不是要写好多东西啊?

可是,用代码写界面的确是这么复杂的,但通过一些字符就可以绘画出一个有意义的界面出来,的确非常有成就感。

四、项目维护

总的来说,到这里我们的项目中的基本功能已经实现了。但是很有可能出现某些不可预料的奇怪情况,bug。遇到bug不要着急,这是提升我们能力的好机会。好在这个项目的数据规模并不复杂,bug的原因经常显而易见。如果真的遇到了不可解决的bug,那么在实现了所有基本功能的前提下,舍弃一些极难实现的功能,也是情有可原的。否则,高端的程序员存在的意义是什么呢?

在项目过程当中遇到问题,可以找我,也可以找其他在Java方面更有研究的同学解决,希望大家可以深刻地理解设计的步骤,对未来设计更大的项目有所帮助。

2015.4.17 C2613次列车上 一稿

2015.4.19 C2076次列车上 二稿

ZHRMoe Studio, 2015.