Java入门:注册模块的实现
1.主活动图
用户选择注册选项,进入注册界面,开始输入注册信息,到最后完成注册。具体的活动图如下:
以上活动图中,矩形框里的操作不是在一个类里面实现的,而是通过Form类和UserService类来实现,Form类负责用户交互,UserService负责处理用户数据。
2.修改UserService类
2.1 UserService类总体分析
UserService负责用户数据的存取,需要根据所要实现的功能来重新设计UserService的成员变量和成员方法。(注意,我们在最初学习理解类的时候,是按照“类是对某类具体事物的抽象形成类”来理解的,也就是说类是描述一类具有相同属性和操作的事物。现在我们这里定义的UserService类并不能按这个思路去理解。UserService是一个抽象的类,并没有跟具体的事物相关联。所以,初学者要了解,类不仅仅是描述学生、动物、大楼、教师这样具体的事物,也可以是一些抽象操作的封装。也就说,将一些具有相关性的操作或属性封装在一起形成一个类,用来完成某一个特定的任务。UserService就是这样的类,我们将与用户相关的操作和属性特征封装在一起,形成UserService类。)
UserService类是给其它模块使用的,对其它代码模块来说,UserService需要提供的功能如下类图所示:
以上类图中,前面带+号的表示是UserService应该提供给其它模块使用的功能(即方法)。
String fileName:用来存储用户数据的文件名称。此文件保存在硬盘上,存储所有用户的数据。类图中前面的-号表示这个成员变量是私有的,不必让其它代码模块访问。
public boolean modifyInfo(User user):修改用户信息。修改成功返回true,用户不存在或存储用户信息的文件有错误时会导致修改失败,修改失败返回false。参数是一个User类的对象(User类定义见第3条)。
public boolean login(String name,String pwd):验证用户登录信息。用户名密码正确返回true,否则返回false。参数只需要用户名、密码即可,所以不需要将参数定义为User对象。
public boolean isExist(String name):验证某个用户名是否已经存在。存在,返回true,否则返回false。
public boolean register(User user):注册用户。返回值true表示注册成功,false表示注册失败。参数是User对象,即需要传入一个User对象才可以注册。注册成功,用户数据会保存到文件里。
了解了UserService类应该具有的核心成员方法和成员变量之后,我们还需要理清实现UserService的逻辑。要搞清一个类的实现逻辑,我们可以从这个类对象的使用角度去分析。
我们使用UserService类时,先是要实例化一个对象,在实例化对象时会调用构造方法。那么,应该在构造方法里写些什么内容呢?一旦实例化好一个UserService对象,我们希望这个对象拥有所有用户的信息,以便在后续代码中可以使用直接这些用户对象。所以,我们就可以在构造函数中去将0文本文件user.txt中描述的用户数据导入进内存,变成内存对象,这样我们后面的代码才可以用到这些User对象。这就是下面UserService.java代码中第13行到第24行的语句所做的事情。在这里,需要搞清楚两点:
1)从文件中读出来的是字符串数据,每行代表一个User对象,需要根据这个字符串所描述的用户信息,创建一个对应的User对象。这个过程在下面的代码中,对应的是toObject(String userStr)方法。
2)将文件中描述的用户转换成对象后,这些对象应该放到哪里去?我们把它放在了一个ArrayList对象users中了,后面注册也好,判断用户名密码也好,都可以直接使用这个链表对象,因为所有用户信息都在它里面放着了,没必要再去读文件了。这个链表对象是一个数组链表对象,这个数组链表可以存放很多元素,属于一个集合类型的对象。有关ArrayList类的用法,请参考Java入门系列:实例讲解ArrayList用法。下面的代码对应的是第18行语句。
UserService.java
1 import java.io.BufferedReader; 2 import java.io.FileReader; 3 import java.io.IOException; 4 import java.util.ArrayList; 5 6 public class UserService { 7 String fileName = "user.txt"; 8 ArrayList<User> users; 9 10 public UserService(){ 11 users = new ArrayList<User>(); 12 13 String line; 14 try{ 15 BufferedReader br = new BufferedReader(new FileReader(fileName)); 16 line = br.readLine(); 17 while(line != null){ 18 users.add(toObject(line)); 19 line = br.readLine(); 20 21 } 22 }catch(IOException e){ 23 e.printStackTrace(); 24 } 25 } 26 27 /** 28 * 验证用户名密码是否正确 29 * @param n 30 * @param pwd 31 * @return true:用户名密码正确,否则返回false。 32 */ 33 public boolean login(String n,String pwd){ 34 for(User u : users){ 35 if(u.name.equals(n) && u.password.equals(pwd)){ 36 return true; 37 }else{ 38 return false; 39 } 40 } 41 return false; 42 43 // if(n.equals("Mike") && pwd.equals("123")){//String类的equals方法,不是使用 == 44 // return true; 45 // }else{ 46 // return false; 47 // } 48 } 49 /** 50 * 修改用户密码 51 * @param name:需要修改密码的用户名称 52 * @param newPwd:新密码 53 * @return 54 */ 55 public boolean modifyPwd(String name,String newPwd){ 56 return true; 57 } 58 59 /** 60 * 注册用户,将用户保存到文件中,同时更新users数组链表 61 * @param user 62 * @return 63 */ 64 public boolean register(User user){ 65 return false; 66 } 67 /** 68 * 讲一个包含用户信息的字符串转换为一个User对象 69 * @param userStr 70 * @return 71 */ 72 private User toObject(String userStr){ 73 String[] temp = userStr.split(" ");//split(“ ”)方法是将userStr字符串按空格进行拆分成几 74 //个部分,这几个部分组成一个String[], 75 return new User(temp[0],temp[1],temp[2]); 76 } 77 78 }
2.2 register(User user)方法分析
这里拿其中一个方法boolean register(User user)来分析一下。
此方法的功能是:注册一个用户,也就是把这个用户信息写到user.txt文件中去。
方法声明语句:boolean register(User user){}。参数user:传递给register方法的用户对象
方法体的活动图:
1)将传递的user添加到users集合中:
users.add(user);
上面一条语句即可将传进来的user对象添加到users数组链表集合中。
2)将users集合写入到user.txt文件中
1 try { 2 BufferedWriter bw = new BufferedWriter(new FileWriter(fileName)); 3 4 for (User u : users) { 5 bw.write(u.name + " " + u.password + " " + u.email); 6 bw.newLine(); 7 } 8 bw.close(); 9 } catch (IOException e) { 10 e.printStackTrace(); 11 }
有关Java文件操作,请参考http://www.cnblogs.com/bayes/p/5478862.html
3.添加User类
User类是描述用户信息的类,代码如下:
User.java
1 public class User { 2 String name; 3 String password; 4 String email; 5 6 public User(String name, String pwd, String email) { 7 this.name = name; 8 this.password = pwd; 9 this.email = email; 10 } 11 }
4.添加RegexUtils类
RegexUtils类专门用来完成用户密码、email合法性的判断。代码如下:
RegexUtils.java
1 import java.util.regex.Pattern; 2 3 public class RegexUtils { 4 /** 5 * 验证Email 6 * @param email email地址,格式:zhangsan@sina.com,zhangsan@xxx.com.cn,xxx代表邮件服务商 7 * @return 验证成功返回true,验证失败返回false 8 */ 9 public static boolean checkEmail(String email) { 10 String regex = "\\w+@\\w+\\.[a-z]+(\\.[a-z]+)?"; 11 return Pattern.matches(regex, email); 12 } 13 14 /** 15 * 验证身份证号码 16 * @param idCard 居民身份证号码15位或18位,最后一位可能是数字或字母 17 * @return 验证成功返回true,验证失败返回false 18 */ 19 public static boolean checkIdCard(String idCard) { 20 String regex = "[1-9]\\d{13,16}[a-zA-Z0-9]{1}"; 21 return Pattern.matches(regex,idCard); 22 } 23 24 /** 25 * 验证手机号码(支持国际格式,+86135xxxx...(中国内地),+00852137xxxx...(中国香港)) 26 * @param mobile 移动、联通、电信运营商的号码段 27 *<p>移动的号段:134(0-8)、135、136、137、138、139、147(预计用于TD上网卡) 28 *、150、151、152、157(TD专用)、158、159、187(未启用)、188(TD专用)</p> 29 *<p>联通的号段:130、131、132、155、156(世界风专用)、185(未启用)、186(3g)</p> 30 *<p>电信的号段:133、153、180(未启用)、189</p> 31 * @return 验证成功返回true,验证失败返回false 32 */ 33 public static boolean checkMobile(String mobile) { 34 String regex = "(\\+\\d+)?1[3458]\\d{9}$"; 35 return Pattern.matches(regex,mobile); 36 } 37 38 /** 39 * 验证固定电话号码 40 * @param phone 电话号码,格式:国家(地区)电话代码 + 区号(城市代码) + 电话号码,如:+8602085588447 41 * <p><b>国家(地区) 代码 :</b>标识电话号码的国家(地区)的标准国家(地区)代码。它包含从 0 到 9 的一位或多位数字, 42 * 数字之后是空格分隔的国家(地区)代码。</p> 43 * <p><b>区号(城市代码):</b>这可能包含一个或多个从 0 到 9 的数字,地区或城市代码放在圆括号—— 44 * 对不使用地区或城市代码的国家(地区),则省略该组件。</p> 45 * <p><b>电话号码:</b>这包含从 0 到 9 的一个或多个数字 </p> 46 * @return 验证成功返回true,验证失败返回false 47 */ 48 public static boolean checkPhone(String phone) { 49 String regex = "(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$"; 50 return Pattern.matches(regex, phone); 51 } 52 53 /** 54 * 验证整数(正整数和负整数) 55 * @param digit 一位或多位0-9之间的整数 56 * @return 验证成功返回true,验证失败返回false 57 */ 58 public static boolean checkDigit(String digit) { 59 String regex = "\\-?[1-9]\\d+"; 60 return Pattern.matches(regex,digit); 61 } 62 63 /** 64 * 验证整数和浮点数(正负整数和正负浮点数) 65 * @param decimals 一位或多位0-9之间的浮点数,如:1.23,233.30 66 * @return 验证成功返回true,验证失败返回false 67 */ 68 public static boolean checkDecimals(String decimals) { 69 String regex = "\\-?[1-9]\\d+(\\.\\d+)?"; 70 return Pattern.matches(regex,decimals); 71 } 72 73 /** 74 * 验证空白字符 75 * @param blankSpace 空白字符,包括:空格、\t、\n、\r、\f、\x0B 76 * @return 验证成功返回true,验证失败返回false 77 */ 78 public static boolean checkBlankSpace(String blankSpace) { 79 String regex = "\\s+"; 80 return Pattern.matches(regex,blankSpace); 81 } 82 83 /** 84 * 验证中文 85 * @param chinese 中文字符 86 * @return 验证成功返回true,验证失败返回false 87 */ 88 public static boolean checkChinese(String chinese) { 89 String regex = "^[\u4E00-\u9FA5]+$"; 90 return Pattern.matches(regex,chinese); 91 } 92 93 /** 94 * 验证日期(年月日) 95 * @param birthday 日期,格式:1992-09-03,或1992.09.03 96 * @return 验证成功返回true,验证失败返回false 97 */ 98 public static boolean checkBirthday(String birthday) { 99 String regex = "[1-9]{4}([-./])\\d{1,2}\\1\\d{1,2}"; 100 return Pattern.matches(regex,birthday); 101 } 102 103 /** 104 * 验证URL地址 105 * @param url 格式:http://blog.csdn.net:80/xyang81/article/details/7705960? 或 http://www.csdn.net:80 106 * @return 验证成功返回true,验证失败返回false 107 */ 108 public static boolean checkURL(String url) { 109 String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?"; 110 return Pattern.matches(regex, url); 111 } 112 113 /** 114 * 匹配中国邮政编码 115 * @param postcode 邮政编码 116 * @return 验证成功返回true,验证失败返回false 117 */ 118 public static boolean checkPostcode(String postcode) { 119 String regex = "[1-9]\\d{5}"; 120 return Pattern.matches(regex, postcode); 121 } 122 123 /** 124 * 匹配IP地址(简单匹配,格式,如:192.168.1.1,127.0.0.1,没有匹配IP段的大小) 125 * @param ipAddress IPv4标准地址 126 * @return 验证成功返回true,验证失败返回false 127 */ 128 public static boolean checkIpAddress(String ipAddress) { 129 String regex = "[1-9](\\d{1,2})?\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))\\.(0|([1-9](\\d{1,2})?))"; 130 return Pattern.matches(regex, ipAddress); 131 } 132 }