做完这个eclipse控制台版本的图书管理系统,感觉略有收获,对类与对象的一些关系,接口的使用,以及HashMap,语句判定等有了更深刻的理解.
而这个系统还会继续进化. 加入数据库, web展示.亦或者使用java图形界面.
1.首先第一步,我要做这个图书管理系统,我更理解为一个图书馆 管理系统, 而不仅仅是图书. 首先java是面向对象的.那么好吧,有一个图书馆接口,一些书架,一些书放在书架上.
之后功能需求要能实现注册,登陆,退出.
登陆之后实现书的借阅,归还.
2.这一步使用了大量的逻辑判定判断,因为觉得是练手的小项目,前期做得有点"冗余",多余的一些杂质让我感觉做不动.通过放低要求,才发现,原来简单而美妙.
package 图书管理系统2; import java.util.HashMap; import java.util.Iterator; import java.util.Scanner; import java.util.Set; public class LoginStuff { static Scanner in = new Scanner(System.in); // 登陆方式选区,通过卡号呢还是用户名密码 public static void loginSelect() { System.out.println("1.刷卡登陆.<输入卡号>\n2.用户名密码登陆.\n#.返回上级"); String loginSelectNum = in.next(); boolean numRight = loginSelectNum.equals("1") || loginSelectNum.equals("2") || loginSelectNum.equals("#"); if (numRight) { if (loginSelectNum.equals("1")) { LoginStuff.loginWithID(); } if (loginSelectNum.equals("2")) { LoginStuff.loginWithUserAndPassword(); } if (loginSelectNum.equals("#")) { Service.getHello(); } } else { System.out.println("输入错误,请输入1或2或#."); System.out.println(); loginSelect(); } } // 执行login(ID)前必须执行该方法 // 使用ID卡号登陆 public static void loginWithID() { System.out.println("请输入您的卡号,以#号结束,(或只输入#返回上一层)"); String ID_numberStr = ""; String nextNumber = in.next(); int OriginalIDlength = Library.IDLength; ID_numberStr = nextNumber.trim(); boolean IDPassed = false; if (ID_numberStr.endsWith("#")) { if (ID_numberStr.length() == 1 && ID_numberStr.equals("#")) { loginSelect(); return; } ID_numberStr = ID_numberStr.replace("#", ""); if (ID_numberStr.length() != OriginalIDlength) { IDPassed = false; System.out.println("正确卡号长度为" + OriginalIDlength + "位.请重新输入:"); } if (ID_numberStr.length() == OriginalIDlength) { IDPassed = true; } } if (IDPassed) { long ID_number = (long) Long.valueOf(ID_numberStr); login(ID_number); } else { loginWithID(); } } // 通过用户名及密码登陆的方法,这一方法只是判定其格式,之后再调用了 login(inputUserName, inputPassWord) public static void loginWithUserAndPassword() { System.out.println("请输入用户名及密码登陆.,(或只输入#返回上一层)"); String inputUserName = in.next(); if(inputUserName.equals("#")) { loginSelect(); return; } String inputPassWord = in.next(); boolean regexFailed = inputUserName == null || inputUserName == "" || inputUserName.length() == 0 || inputPassWord == null || inputPassWord == "" || inputPassWord.length() == 0; while (regexFailed) { System.err.println("用户名或密码不能为空!"); loginWithUserAndPassword(); } if (!regexFailed) { login(inputUserName, inputPassWord); } } // 登陆方式的选择2, 通过用户名和密码登陆 之前已经使用loginWithUserAndPassword()进行了用户名和密码的接受和格式判定 // 而这一步是判定用户数据库的userList中和输入的用户名密码进行比对,如果正确则提示登陆成功, // 如果对比失败则重新调用loginWithUserAndPassword()方法进行用户名和密码的接受和判定,其后再这个login方法进行比对.循环往复 public static void login(String userName, String passWord) { Set<User> userList = UserDatabase.getUserInstance(); boolean userInList = false; boolean userAuthPassed = false; String thisNick = null; String pass = null; User thisUser_ = null; Iterator<User> userIt = userList.iterator(); while (userIt.hasNext()) { thisUser_ = userIt.next(); if (userName.equals(thisUser_.getUserName())) { pass = thisUser_.getPassWord(); userInList = true; } if (userInList) { if (passWord.equals(pass)) { userAuthPassed = true; thisNick = thisUser_.getNickName(); break; } } } // 登陆通过之后 if (userAuthPassed) { System.out.println(thisNick + "登陆成功!"); System.out.println("快和小伙伴们一起玩耍(看书)吧!"); MemberService.showMemberSerivce(thisUser_); } else { System.out.println("账号或密码错误,请重新登陆!"); loginWithUserAndPassword(); } } // 通过用户ID进行登陆,先通过User中的IDNumberSet这个Set集合进行取出, // 使用了IDNumberJudge(Long ID)方法进行了"是否有这个ID"的比对 public static void login(long ID_Number) { long inputID = User.getID_number(); // 该boolean值就是去确定是否有这个ID号码,有则为true.没有这个ID也就是 // 说明用户ID是不存在的,不能登陆,其后可以再设置让其进行注册 boolean IDReady = User.IDNumberJudge(inputID); if (IDReady) { HashMap<Long, User> userData = UserDatabase.getUserDataMap(); User thisUser = userData.get(inputID); System.out.println("------------------------"); System.out.println(thisUser); System.out.println("刷卡成功,可以随意看书啦.当您离开记得再次刷卡以扣除时间段内消费!"); System.out.println("------------------------"); MemberService.showMemberSerivce(thisUser); } else { System.out.println("抱歉,没有找到关于您卡号的信息!请稍后再试.如需帮助请联系管理员."); System.out.println("或者您也可以进行使用面板的1号选项进行注册."); Service.getHello(); } } }
package 图书管理系统2; import java.util.HashMap; import java.util.Iterator; import java.util.Scanner; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegisterStuff { static Scanner in = new Scanner(System.in); private static String userName; private static String passWord; private static String sex; private static String nickName; private static int age; public User newRegisterStuff(String username, String password1, String password2, String sex, String nickname, int age) { String regex = "^[a-zA-Z0-9\u4E00-\u9FA5]+$"; Pattern pattern = Pattern.compile(regex); Matcher match = pattern.matcher(username); boolean b = match.matches(); int alreadyHasUserName = 1; boolean userNamePassed = (username != "" || username != null || username.length() != 0); if (userNamePassed) { if (!b) { System.out.println("用户名只能由数字字母和下划线组成!请重新输入!"); register(); // return; } else { // 用户名格式通过后,再判定用户名是否存在于已有用户的用户名字段中,已存在则返回true,不存在返回false alreadyHasUserName = userNameAgain(username); if (alreadyHasUserName == 1) {// 已经存在该账户名,则重新输入 // 去判定用户名有一个什么标记才行呢?使用boolean和int去判定最终还是会不行. System.out.println("该用户名已经存在,请选用其他用户名~"); username = null; register(); // return; } else if (alreadyHasUserName == 0) {// 不重复则通过,并赋值给this.userName this.userName = username; } } } else { while (!userNamePassed) { System.out.println("用户名为空,请重新填写注册信息."); register(); // return; } } // 判定密码 boolean passwordPassed = password1.equals(password2); if (passwordPassed) { this.passWord = password1; } else { while (!passwordPassed) { System.out.println("密码两次不一致,请核对后再次输入!(只输入两次密码)"); String password_ = in.next(); String password2_ = in.next(); passwordPassed = passWordAgain(password_, password2_); if (passwordPassed) { this.passWord = password_; } } } // 判定性别输入 (不足)英文只支持小写. boolean sexPassed = (sex.equals("男") || sex.equals("女") || sex.equals("man") || sex.equals("man") || sex.equals("woman") || sex.equals("boy") || sex.equals("girl")); if (sexPassed) { this.sex = sex; } else { while (!sexPassed) { System.out.println("性别填写错误,请再次填写:"); String sex_ = in.next(); sexPassed = sexAgain(sex_); if (sexPassed) { this.sex = sex_; } } } // 判定昵称合法性 boolean nickNamePassed = (nickname != "" || nickname != null || nickname.length() != 0); if (nickNamePassed) { this.nickName = nickname; } else { while (!nickNamePassed) { System.out.println("昵称为空,请再次填写:"); String nickname_ = in.next(); nickNamePassed = nickNameAgain(nickname_); if (nickNamePassed) { this.nickName = nickname_; } } } // 判断年龄合法性 boolean agePassed = (age < 999 && age > 0); if (agePassed) { this.age = age; } else { while (!agePassed) { System.out.println("只接受0岁以上儿童以及999岁以内的银河系生物!请再次输入年龄!"); int age_ = in.nextInt(); agePassed = ageAgain(age_); if (agePassed) { this.age = age_; } } } // 结束了所有数据的判断 ///////////////////////////////////////////////////////////////////////////////// boolean AuthPassed = alreadyHasUserName == 0 && userNamePassed && b && passwordPassed && sexPassed && nickNamePassed && agePassed; User newUser = null; // 如果注册成功则创建新user对象. if (AuthPassed) { newUser = new User(this.userName, this.passWord, this.sex, this.nickName, this.age); } return newUser; }// RegisterStuff(.......注册信息.......)_END private static String getUserName() { return userName; } private static String getPassWord() { return passWord; } private static String getSex() { return sex; } private static String getNickName() { return nickName; } private static int getAge() { return age; } public RegisterStuff() { } // 注册 public static void register() { System.out.println("请输入您的>>账户名<<>>密码<<>>确认密码<<>>性别<<>>昵称<<>>年龄<<\n以空格隔开~(*^_^*)"); RegisterStuff rs = new RegisterStuff(); User newUser = rs.newRegisterStuff(in.next(), in.next(), in.next(), in.next(), in.next(), in.nextInt()); if (newUser != null) { registerToUser(newUser);// 在将注册信息注册入了用户数据库后. 可能会为null 此时在这个方法中判断 printOK(newUser);// 登陆成功提示,并提示用户的昵称等. } } // 注册完成后用户数据放入UserDatabase public static void registerToUser(User newUser) { UserDatabase.setUserNameList(newUser.getUserName()); UserDatabase.setUserInstance(newUser); HashMap<Long, User> userDatabaseInRegister = UserDatabase.getUserDataMap(); long ID = newUser.getID_number(); userDatabaseInRegister.put(ID, newUser); UserDatabase.setUserData(userDatabaseInRegister); // 注册信息已送入UserDatabase 可以将用户数据使用IO写入txt文件 } // // 最后补的 暂未加入 // public static void afterRegister() { // printOK(); // BookShelf bs = new BookShelf(); // bs.BookShelfInit(); // bs.getAllCategory(); // System.out.println("请问你要查阅哪些书籍?或哪一本?"); // } // 注册成功之后 private static void printOK(User user) { System.out.println("注册成功!"); HashMap<Long,User> userInstanceInRegister = UserDatabase.getUserDataMap(); User thisUser = userInstanceInRegister.get(user.getID_number()); System.out.println("***"+thisUser+"***"); } // 从数据库取出用户名,查看这次的用户是否存在重复 public int userNameAgain(String userName) { // 从用户数据库List获取已经存在的账户对象 Set<String> userAlreadyHave = UserDatabase.getUserNameList(); // 从数据库取出,去判定用户名是否存在,单独写个方法 for (String alreadyHaveName : userAlreadyHave) { if (userName.equals(alreadyHaveName)) { return 1;// 重复用户名返回1 } } // 不重复用户名返回0 return 0; } // 重新写入passWord属性 public boolean passWordAgain(String password1, String password2) { if (password1.equals(password2)) { System.out.println("本次密码核对正确!"); return true; } return false; } // 重新写入sex属性 private boolean sexAgain(String sex_) { if ((sex_.equals("男") || sex_.equals("女") || sex_.equals("man") || sex_.equals("man") || sex_.equals("woman") || sex_.equals("boy") || sex_.equals("girl"))) { return true; } return false; } // 重新写入nickName属性 public boolean nickNameAgain(String nickname_) { if (nickname_ != "" || nickname_ != null || nickname_.length() != 0) { return true; } return false; } // 重新写入age属性 public boolean ageAgain(int age_) { if (age_ < 999 && age_ > 0) { return true; } return false; } }
3. 有了登陆注册,在用户登陆后要提供会员服务,我直接建立了一个MemberService类.其实还有管理员Service和计算机Service类,应该提取某些Service作为一个Service接口,不过还没想好.
package 图书管理系统2; import java.util.ArrayList; import java.util.HashMap; import java.util.Scanner; import java.util.Set; public class MemberService { static Scanner in = new Scanner(System.in); public static void showMemberSerivce(User thisUser_) { System.out.println("您好," + thisUser_.getNickName() + ",这是会员服务栏目,您可享受一下服务,Enjoy it!"); System.out.println("1.借书\t\t2.还书\n3.点个咖啡\t\t4.上网冲浪\n5.健身运动\t\t6.图书馆留言\n#.返回上级目录(退出登陆)"); String serNum = in.next(); switch (serNum) { case "1":borrowBookSer(thisUser_); break; case "2":giveBackBookSer(thisUser_); break; case "3": break; case "4": break; case "5": break; case "6": break; case "#":LoginStuff.loginSelect(); break; default: System.out.println("请输入正确的服务选择~!"); showMemberSerivce(thisUser_); break; } } public static void borrowBookSer(User user) { System.out.println("您好"+user.getNickName()+",请问您想借阅哪本书呢?"); HashMap<String, Books> books = BookShelf.getBookMap(); Set<String> bookNames = books.keySet(); for(String bns : bookNames) { System.out.print(bns+" : "+books.get(bns).beBorrowed); } System.out.println("输入书名,借阅书籍."); String wantedBook = in.next(); user.borrow(books.get(wantedBook)); showMemberSerivce(user); } public static void giveBackBookSer(User user) { System.out.println("您好"+user.getNickName()+",请问您想还哪本书呢?"); ArrayList<String> userBorrowedBooks = user.getBorrowedBooks(); if(userBorrowedBooks == null) { System.out.println("抱歉您没有书要还~"); return; } System.out.println("您借阅的书此时还有如下:"); int hasBorrowedCount = 0; for(String books:userBorrowedBooks) { hasBorrowedCount++; System.err.println(books); } if(hasBorrowedCount != 0) { System.out.println("请输入您要还的书的书名~:"); String giveBackBookName = in.next(); //从用户已借阅列表中删除这本书 boolean giveback = userBorrowedBooks.remove(giveBackBookName); HashMap<String, Books> bookInstanceMap =BookShelf.getBookMap(); Books backBookInstance = bookInstanceMap.get(giveBackBookName); user.giveBack(backBookInstance, giveback); showMemberSerivce(user); }else { System.err.println("Sorry,您没有书要还~"); showMemberSerivce(user); } } }
还有很多代码就不贴了直接上https://www.processon.com/view/link/5b24b04ae4b06d15ca94aedb
请见谅为了方便查阅,包名使用了中文.
通过做这个系统,感觉对类和对象的概念更清晰了,接口使用和一些冗余还是有待加强.
最近看<重构>这书觉得还是有些许作用,比如当感觉必须要规整一下编码,把类似的放到一起,或者按照某些原则,这些我还是不太懂.
总之,收获颇丰~~~
将编程看作是一门艺术,而不单单是个技术。 敲打的英文字符是我的黑白琴键, 思维图纸画出的是我编写的五线谱。 当美妙的华章响起,现实通往二进制的大门即将被打开。