2012-03-26 6 views
7

実用的なプログラミングの原則を維持しようとしている私は、「尋ねる、尋ねないでください」という原則に基づいてユーザーパスワードの変更を扱う方法を決定しようとしています。原則とパスワードの有効期限を尋ねることを教えてください

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

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

+1

期限切れのパスワードは愚かなことです。人々はちょうど彼らが再びそれを変更する必要があるときに複雑なものを覚えていた*ので*偽ったものを使用する傾向があります。 – ThiefMaster

+0

PCIに準拠していない – Hupperware

+0

@Hupperware figure that :-p – jnm2

答えて

3

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

+0

これは別の原則を破っています。例外を使ってフローを制御しないでください。期限切れのパスワードは例外的な状況ではありません。 – NOtherDev

+0

制御フローに例外を使用しないでください。高価です。 –

+0

良い点、ありがとうございます。しかし、あなたが「Tell、Do not Ask」に固執したいのであれば、例外なくこれをどう扱うことができますか?関数から状態を返しますか? – GavinCattell

3

ユーザーオブジェクトに(メンバーシッププロバイダー契約のように)ブール値を提供するValidate()メソッドを持たせるか、Validate()メソッドで検証の結果を示す何らかの並べ替えを返すことを検討する必要があります(OK、INVALID_PASSWORD、EXPIRED_PASSWORDなど)。

パスワードの有効期限が切れても、例外をスローすることはできません。ランタイムがスタックを巻き戻さなければならないので、それは悪いフォームであり、パフォーマンスヒットです。

+0

私はこの議論を理解したことはありません...スタックは自分自身を解くのにはかなり良いです。それはそれが意味するものです。 – DanDan

+0

テストを行います。例外をスローするコンソールアプリケーションを作成し、出力をコンソールに書き込みます。デバッグモードで実行します。例外がスローされて表示されるまでにどれくらい時間がかかります。あなたが例外を投げるときには、多くのことが起こっています - それは高価です。また、デバッグはリリースモードで実行するよりも遅いことも理解していますが、例外をスローするとまだ多くのことが起こっています。 –

+0

これは問題ありません...私の例外オブジェクトは例外なく処理されますが、豊富な情報でいっぱいだから問題に対処するのに最適な場所にいます。構築に数ナノ秒かかるかどうかは気にしません。 – DanDan

1

私は個人的にarround戻り値/ 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(); 
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() 

、一切の例外を掲載していない、そしてそれはデメテル

の法則に従うしないでください、知らせます
0

これを解決する1つの方法は、このようなオブジェクト指向モデリングです:

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) { 
    ... 
} 
} 

このようにして、他のドメインオブジェクトに何かを尋ねるのではなく、ログインに認証するように指示します。

関連する問題