7

実用的なプログラミングの原則を維持しようとして、「Tell, Don't Ask」の原則に基づいてユーザー パスワードの変更を処理する方法を決定しようとしています。

パスワードが 30 日ごとに期限切れになるユーザー オブジェクトがあります。パスワードの有効期限が切れている場合、パスワードの有効期限が切れている/パスワードの変更ビューを表示できるようにする必要があります。パスワードの有効期限が切れているかどうか (状態) をオブジェクトに尋ねてから、表示するビューを選択することは、原則に違反しているように思えます。

この状況を処理する最善の方法は何ですか?

4

5 に答える 5

4
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()

教えて、聞かないで、例外なく、デメテルの法則に従う

于 2012-03-26T21:45:59.543 に答える
3

パスワードが認証されたとき、またはユーザーに対して最初に呼び出した関数が何であれ、ユーザーオブジェクトから PasswordExpired 例外をスローできます。

于 2012-03-26T19:49:48.690 に答える
3

ユーザー オブジェクトにブール値を提供する Validate() メソッドを持たせるか (メンバーシップ プロバイダー コントラクトのように)、または Validate() メソッドが検証の結果を示すある種の列挙型を返すようにすることを検討する必要があります (OK、INVALID_PASSWORD 、EXPIRED_PASSWORD など)。

多くのオプションがあります - パスワードの有効期限が切れている場合、例外をスローすることはそれらの 1 つであってはなりません。ランタイムがスタックをアンワインドする必要があるため、これは悪い形式であり、パフォーマンス ヒットでもあります。

于 2012-03-26T19:55:10.657 に答える
1

私は個人的に、戻り値/Enum型の周りをプログラムするのは好きではありません。戻り値の型が多いほど、テスト/操作する必要があるパスが多くなります。また、例外を使用してフローを制御することは、悪い習慣です (他のオプションが本当に見つからない場合を除きますが、通常はより良いオプションがあります)。

期限切れのパスワードは、私にとって特別なことではありません。結局のところ、それは有効な状態です(または、パスワードに対して何かをして、まったく期限切れになるでしょう)

私はそれを単純に保ち、呼び出し元が直接呼び出すことができるaboolまたは a のようなものを返すようにしています。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();
于 2012-03-26T20:54:21.980 に答える
0

これを解決する 1 つの方法は、次のような OO モデリングです。

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 に認証を指示します。

于 2013-01-26T18:02:52.513 に答える