我试图通过使用不同的小项目来测试自己,而不是在一本书中读到关于java的内容,从而使我在java方面有了更好的表现。我制作了一个简单的登录/注册系统来尝试处理继承和抽象类。我所有的代码都在下面。尽管批评代码,告诉我你会做的更好。我这么做的原因是,我只想看看其他人会如何处理这样的项目,希望我能学到一些东西。
//RegLogSysDriver.java
public class RegLogSysDriver {
public static void main(String[] args) {
RegLogSystem system = new RegLogSystem();
system.run();
}
}//RegLogSystem.java
import java.util.Scanner;
public class RegLogSystem {
//Instance variables
Scanner input = new Scanner(System.in);
String regOrLogInput;
String name, dateOfBirth, email, password;
//Methods
public void run() {
boolean keepGoing = true;
while(keepGoing==true) {
System.out.println("Do you wish to (l)ogin or (r)egister");
regOrLogInput = input.nextLine();
if(regOrLogInput.contentEquals("l")) {
System.out.println("Enter email:\n");
email = input.nextLine();
System.out.println("Enter password:\n");
password = input.nextLine();
LoginForm lForm = new LoginForm(email, password);
lForm.executeForm();
}else if(regOrLogInput.contentEquals("r")) {
System.out.println("Enter name:\n");
name = input.nextLine();
System.out.println("Enter date of birth e.g. (03/04/2000):\n");
dateOfBirth = input.nextLine();
System.out.println("Enter email:\n");
email = input.nextLine();
System.out.println("Enter password:\n");
password = input.nextLine();
RegisterForm rForm = new RegisterForm(name, dateOfBirth, email, password);
rForm.executeForm();
}
System.out.println("Do you wish to shutdown the system, (y)es or (n)o?");
String inputText = input.nextLine();
if(inputText.contentEquals("y")) {
keepGoing = false;
}
}
}
}//LoginForm.java
public class LoginForm extends Form{
public LoginForm(String email, String password) {
super(email, password);
}
@Override
public void executeForm() {
if(getDataBase().isUserRegistered(getEmail(), getPassword())) {
User newUser = getDataBase().getUser(getEmail(), getPassword());
WelcomePage welPage = new WelcomePage(newUser);
welPage.outputMessage();
welPage.logoutMessage();
}else {
//put error handling here in time.
System.out.println("User is not registered");
}
}
}//RegisterForm.java
public class RegisterForm extends Form{
private String name;
private String dateOfBirth;
public RegisterForm(String name, String dateOfBirth, String email, String password) {
super(email, password);
this.name = name;
this.dateOfBirth = dateOfBirth;
}
public String getName() {
return this.name;
}
public String getDateOfBirth() {
return this.dateOfBirth;
}
@Override
public void executeForm() {
User newUser = new User(getName(), getDateOfBirth(), getEmail(), getPassword());
getDataBase().addUserToDatabase(newUser);
WelcomePage welPage = new WelcomePage(newUser);
welPage.outputMessage();
welPage.logoutMessage();
}
}//Form.java
public abstract class Form {
private String emailEntry;
private String passwordEntry;
private Database dataBase;
protected Form(String emailEntry, String passwordEntry) {
this.dataBase = new Database();//both forms are going to need access to the same database
this.emailEntry = emailEntry;
this.passwordEntry = passwordEntry;
}
public String getEmail() {
return this.emailEntry;
}
public String getPassword() {
return this.passwordEntry;
}
public Database getDataBase() {
return this.dataBase;
}
public abstract void executeForm();
}//User.java
public class User {
private String name;
private String dateOfBirth;
private String email;
private String password;
public User(String name, String dateOfBirth, String email, String password) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.email = email;
this.password = password;
}
public User() {
}
public String getEmail() {
return this.email;
}
public String getPassword() {
return this.password;
}
public String getName() {
return this.name;
}
public String getDateOfBirth() {
return this.dateOfBirth;
}
}//Database.java
import java.util.ArrayList;
public class Database {
private static ArrayList<User> dataBase = new ArrayList<User>();
static {
dataBase.add(new User("Tom", "12/02/09", "t@gmail.com", "pass"));
dataBase.add(new User("Bryan", "01/01/01", "b@gmail.com", "password"));
dataBase.add(new User("Tarence", "15/22/20", "tt@gmail.com", "passwordismypassword"));
}
public boolean isUserRegistered(String email, String password) {
boolean returnVal = false;
for(User regedUser : dataBase) {
if(regedUser.getEmail().contentEquals(email)&®edUser.getPassword().contentEquals(password)) {
returnVal = true;
}
}
return returnVal;
}
public User getUser(String email, String password) {
User returnVal = new User();
for(User regedUser : dataBase) {
if(regedUser.getEmail().contentEquals(email)&®edUser.getPassword().contentEquals(password)) {
returnVal = regedUser;
}
}
return returnVal;
}
public void addUserToDatabase(User newUser) {
dataBase.add(newUser);
}
}//WelcomPage.java
import java.util.Scanner;
public class WelcomePage {
private User loggedInUser;
private Scanner input = new Scanner(System.in);
public WelcomePage(User loggingInUser) {
this.loggedInUser = loggingInUser;
}
public void outputMessage() {
System.out.println("Hi "+loggedInUser.getName());
}
public void logoutMessage() {
boolean keepGoing = true;
while(keepGoing==true) {
System.out.println("Do you wish to logout, (y)es or (n)o");
String inputText = input.nextLine();
if(inputText.contentEquals("y")) {
keepGoing=false;
}
}
}
}发布于 2021-02-19 14:01:06
到目前为止看起来还不错!这里有几件我注意到的事情,或者我会改变的事情,没有什么特别的顺序。
contentEquals()这用于与StringBuffer或StringBuilder进行比较。在您的情况下,这太过分了,最好使用equals()或equalsIgnoreCase()。
很多时候你做了这样的事
boolean keepGoing = true;
while(keepGoing==true) {
...
if( ... ) {
keepGoing=false;
}
}与true或false相比是不需要的。如果变量名得很好,则这比比较更易读。
boolean keepGoing = true;
while(keepGoing) {
...
if( ... ) {
keepGoing=false;
}
}您也可以永远循环,然后break退出循环。
while(true) {
...
if( ... ) {
break;
}
}我不知道,谢谢!但是,如果加载数据库需要花费更长的时间,这将导致第一个用户在首次加载类而不是在程序启动时执行静态块时登录/注册的奇怪延迟。现在我不会更改它,但是如果这成为一个问题,您可以始终将块更改为静态方法,并在程序启动时调用它,在run处理RegLogSystem之前的某个地方。
Database类使用这个实现的方式是可行的,但是为每个表单创建一个新的Database对象并不是真正需要的。相反,您可以使Database类中的所有内容都是静态的,只需执行Database.isUserRegistered(...)而不是getDatabase().isUserRegistered(...)。
isUserRegistered()和getUser()这两种方法都可以在找到具有该密码和电子邮件的用户时立即返回。这样,我们不仅保存了一个变量,而且还保存了空的User构造函数(这也可以用null来初始化,而不是使用无效的用户objectx)。通过这样做,我们也不总是循环整个数据库,节省一些时间。
public boolean isUserRegistered(String email, String password) {
for (User regedUser : dataBase) {
if (regedUser.getEmail().contentEquals(email) && regedUser.getPassword().contentEquals(password)) {
return true
}
}
return false;
} public User getUser(String email, String password) {
for (User regedUser : dataBase) {
if (regedUser.getEmail().contentEquals(email) && regedUser.getPassword().contentEquals(password)) {
return regedUser;
}
}
return null;
}如果您决定在不事先调用getUser()的情况下调用isUserRegistered(),您可能需要小心空值(或空用户)。
还可以将长if-条件提取到User类的方法中,以提高可读性,如下所示:
public boolean checkLoginCreds(String email, String password) {
return this.getEmail().equals(email) && this.getPassword().equals(password);
}使用方式如下:if (regedUser.checkLoginCreds(email, password)) ...
RegLogSystem实例变量不应该是公共的,据我所见,这些变量不需要是实例变量,而是可以作为函数内部的vars在run()方法的顶部声明。
作为一个想法,这个类不能也扩展Form吗?还没有尝试过,但是看看每个表单是如何表示“状态”的,这可以很好地解决问题。
另一个想法是将输入移动到Forms,以便每个人只处理自己的输入,而不是更多,清理RegLogSystem。也许您甚至可以为此向Form类添加一个抽象方法。
https://codereview.stackexchange.com/questions/255478
复制相似问题