防止创建重复帐户,无限量的消息

Preventing duplicate accounts from being made, infinite amount of messages

我一直在为我的计算机科学内部评估编写代码,我快要完成了,但一直发现这个错误,我不确定如何解决它。

这是该部分的代码:

JButton createbutton = new JButton("Create");
createbutton.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        String[] characters = { "!", "#", "$", "%", "^", "&", "*" };
        boolean passcontains = false;
        for (int i = 0; i < characters.length; i++) {
            if (new String(passwordfield.getPassword()).contains(new String(characters[i]))) {
                passcontains = true;
            }
        }
        boolean emcontains = false;
        for (int i = 0; i < characters.length; i++) {
            if (new String(emailfield.getText()).contains(new String(characters[i]))) {
                emcontains = true;
            }
        }
        loop: if (passwordfield.getPassword().length == 0
                || passwordfield.getPassword().length < 8
                || passcontains == false) {
            message("INCORRECT PASSWORD\ncheck README");
        } else {
            if (emailfield.getText().length() == 0 || emcontains
                    || emailfield.getText().contains("@") == false
                    || emailfield.getText().contains(".") == false) {
                message("INCORRECT EMAIL\ncheck README");
            } else {
                boolean pass = true;
                for (int i = 0; i < database.size(); i++) {
                    if (database.get(i).getEmail() == emailfield.getText()) {
                        pass = false;
                    }
                }
                if (pass == true) {
                    database.add(
                            create(emailfield.getText(), new String(passwordfield.getPassword())));
                    write();
                    frame.setVisible(false);
                    message("SUCCESSFULLY MADE ACCOUNT");
                    frame.dispose();
                } else {
                    message("AN ACCOUNT WITH THAT EMAIL ALREADY EXISTS\n GO TO LOGIN");
                    emailfield.setText("");
                    passwordfield.setText("");
                    break loop;
                }
            }
        }
    }
});

编辑: 我自己解决了这个问题,我有一个函数去 'create(input1, input2)' 但由于我以前版本的代码,检查算法包含在其中,因此它完成了两次检查并进入了一个 while 循环。 感谢您的回复。

不要那样做!

关注Separation of Concerns and Single Responsibility Principle.

不要将此类逻辑放入负责向用户显示内容的代码中。让应用程序的业务逻辑远离 GUI 代码。创建一些 classes 并将带有逻辑的代码放在那里。然后在你的 GUI 中你将以一种简单的方式调用这段代码,一切都会变得更好。事实上,这是一个学校项目,并不意味着您交付了“正常工作”的代码。

检查我的方法:

public class Account {

    private final Email email;
    private final Password password;

    public Account(Email email, Password password) {
        Objects.requireNonNull(email, "An account cannot have null email");
        Objects.requireNonNull(email, "An account cannot have null password");
        this.email = email;
        this.password = password;
    }

    public Email getEmail() {
        return email;
    }

    public Password getPassword() {
        return password;
    }

    public static class InvalidAccountInformationException extends RuntimeException {

        public InvalidAccountInformationException(String message) {
            super(message);
        }
    }
}

.

public class Email {
    private final String value;

    private Email(String value) {
        this.value = value;
    }

    public String value() {
        return value;
    }

    // Eclipse generated
    @Override
    public int hashCode() {
        return Objects.hash(value);
    }

    // Eclipse generated
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Email other = (Email) obj;
        return Objects.equals(value, other.value);
    }

    public static Email of(final String email) {
        if (email == null)
            throw new InvalidAccountInformationException("Email cannot be empty.");

        String trimmedEmail = email.trim();

        if (trimmedEmail.isEmpty())
            throw new InvalidAccountInformationException("Email cannot be empty.");

        if (!isValidEmailAddress(trimmedEmail))
            throw new InvalidAccountInformationException("Email is not a valid email address.");

        return new Email(trimmedEmail);
    }

    /*
     * Shamelessly copy-pasta from 
     */
    private static boolean isValidEmailAddress(String email) {
        String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\[[0-9]{1,3}\.[0-9]{1,3}"
                + "\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";
        java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
        java.util.regex.Matcher m = p.matcher(email);
        return m.matches();
    }
}

.

public class Password {
    private static final String[] MANDATORY_CHARACTERS = { "!", "#", "$", "%", "^", "&", "*" };
    private final String value;

    private Password(String value) {
        this.value = value;
    }

    public String value() {
        return value;
    }

    public static Password of(final String pass) {
        if (pass == null || pass.trim().isEmpty())
            throw new InvalidAccountInformationException("Password cannot be empty.");

        if (!containsAtLeastOneMandatoryCharacter(pass))
            throw new InvalidAccountInformationException("Password is too weak.");

        return new Password(pass);
    }

    private static boolean containsAtLeastOneMandatoryCharacter(String pass) {
        return Stream.of(MANDATORY_CHARACTERS).anyMatch(pass::contains);
    }

    // Eclipse generated
    @Override
    public int hashCode() {
        return Objects.hash(value);
    }

    // Eclipse generated
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Password other = (Password) obj;
        return Objects.equals(value, other.value);
    }

}

.

public class AccountDatabase {

    private final List<Account> accounts = new ArrayList<>();

    public void save(Account account) {
        Objects.requireNonNull(account, "Account should not be null");

        if (emailIsAlreadyTaken(account))
            throw new InvalidAccountInformationException("Email is already taken by another user.");

        accounts.add(account);
    }

    private boolean emailIsAlreadyTaken(Account account) {
        return accounts.stream().map(Account::getEmail).anyMatch(account::equals);
    }
}

然后,在 GUI(ActionListener)中,代码如下所示:

AccountDatabase database = ...

try {
    Email email = Email.of(emailField.getText());
    Password pass = Password.of(passwordField.getText());

    Account account = new Account(email, pass);

    database.save(account);
} catch (InvalidAccountInformationException ex) {
    showToUser(ex.getMessage());
    resetTextFieldsToEmptyTextSoUserCanFillThemAgain();
}

你取得了什么成就?始终保持一致的状态!您的应用程序将永远不允许 non-valid 密码。你想添加或删除密码验证,如长度等?您编辑密码 class。不是一些奇怪的,充满噪音的class。您的 GUI 对包含实际逻辑的 classes 进行简单调用。

此外,您实现了可测试性。您将如何在 automated-way 中测试您的 GUI 代码?这是一个复杂的主题,而且肯定不是通过 UI 测试应用程序逻辑的最佳方式。将逻辑和规则提取到其他 classes,你可以“只是测试它们”:

public class PasswordShould {

    @Test
    void not_be_valid_when_is_empty() {
        assertThrows(RuntimeException.class, () -> Password.of(null));
        assertThrows(RuntimeException.class, () -> Password.of(""));
        assertThrows(RuntimeException.class, () -> Password.of("  "));
    }

    @Test
    void not_be_valid_when_is_weak() {
        assertThrows(RuntimeException.class, () -> Password.of("1234"));
        assertThrows(RuntimeException.class, () -> Password.of("GGfdsfds12312"));
    }

    @Test
    void be_valid_when_is_strong() {
        assertDoesNotThrow(() -> Password.of("GGf##dsfds12312"));
    }
}

我的代码可能需要消化很多,但我建议尝试理解它。首先,看一下可读性。你来这里,是因为你无法调试自己的代码。嗯...我们也不能。