Скажите, не спрашивайте принцип и срок действия пароля

Пытаясь придерживаться прагматических принципов программирования, я пытаюсь решить, как обрабатывать изменения пароля пользователя, основываясь на принципе "говори, не спрашивай".

У меня есть объект пользователя, пароль которого истекает каждые 30 дней. Я должен быть в состоянии показать пароль истек / изменить пароль, если срок действия пароля истек. Запрос объекта, если срок действия пароля истек (его состояние), а затем выбор вида для отображения, кажется нарушением принципа.

Каков наилучший способ справиться с этой ситуацией?

5 ответов

login
   model.validate();
   return model.show(self);

passwordExpired()
  return View("ChangePassword")

loginSuccess()
  return View("default")

class User
  show(aController)
      if passwordExpired
          return aContoller.passwordExpired()
     else return aContoller.loginSuccess()

Скажите, не спрашивайте, без исключений, и он подчиняется закону Деметры

Вы можете выдать исключение PasswordExpired из объекта пользователя, когда пароль аутентифицирован, или любую функцию, которую вы сначала вызываете для пользователя.

Вам следует подумать о том, чтобы пользовательский объект имел метод Validate(), который предоставляет логическое значение (как это делается в контракте с поставщиком членства), или подумал о том, чтобы метод Validate() возвращал какое-то перечисление, которое указывает результат проверки (ОК, INVALID_PASSWORD)., EXPIRED_PASSWORD и т. Д.).

Есть много вариантов - исключение не должно быть одним из них, если срок действия пароля истек. Это плохая форма, а также снижение производительности, так как среда выполнения должна разматывать стек.

Я лично не люблю программировать возвращаемые значения / Enum типы. Чем больше типов возврата у вас есть, тем больше путей вы должны протестировать / использовать. Кроме того, использование исключений для управления потоком является плохой практикой (если вы действительно не можете найти какой-либо другой вариант, но обычно есть лучший вариант).

Пароль с истекшим сроком не является действительно исключительным для меня. В конце концов, это действительное состояние (иначе вы могли бы сделать что-то с паролями, чтобы вообще истечь)

Я стараюсь быть проще и возвращаю bool или что-то вроде Func<T> который может быть непосредственно вызван вызывающим абонентом.

Наверное, что-то вроде этого:

public class User
    {
        private DateTime _lastChangeDate;
        public Action Validate()
        {
            if (_lastChangeDate >= DateTime.Now.AddDays(-30))
            {
                return new Action(() => this.Login());
            }
            else
            {
                return new Action(() => this.ChangePassword());
            }
        }
        private void Login()
        {
            Console.WriteLine("Login");
        }
        private void ChangePassword()
        {
            Console.WriteLine("Change Password");
        }
    }

На стороне звонящего:

user.Validate().Invoke();

Одним из способов решения этой проблемы является моделирование ОО, например, так:

public class Login {

private String userName;
private String password;
private Date expirationDate;    

public void authenticate(String password) {
    if (this.password.equals(password) {
        redirectoToMainOrEditPage();
    } else {
        redirectToFailPage();
    }
}

private void redirectToMainOrEditPage() {
    Date today = new Date();

    if (today.before(expirationDate)) {
        redirectToMainPage();
    } else {
        redirectToEditPage();
    }
}

private void redirectToMainPage() {
    ...
}

private void redirectToEditPage() {
    ...
}

private void redirectToFailPage() {
    ...
}

public void changePassword(String newPassword) {
    ...
}

public void changeExpirationDate(Date newDate) {
    ...
}
}

Таким образом, вы ничего не спрашиваете к другим объектам домена, но говорите Login для аутентификации, поскольку у него есть все необходимое для этого.

Другие вопросы по тегам