こんなValidatorは許されない
PasswordValidator.IsValid(passwordString);
ある日、こんなコードを見つけました。引数の型はstring。PasswordValidatorで正当性をチェックしているというのは一目見て明らかです。
では、これは具体的に何をチェックしているんでしょう?
- 文字列の長さ?
- パスワードに使える文字の種類?
- 大文字小文字に記号や数字を要件に従って含んでいること?
- 過去に設定されたパスワードとの重複していないこと?
このコードだけを見ると、サービスのパスワード要件を満たしているかどうかを判定してくれることを期待します。上の箇条書きなら全部。
しかし残念なことに、これは文字列の長さしか見ていませんでした。何がValidだというのか。
幸いなことにこれのすぐ下に文字種などのチェックがそのまま書いてあったので、モジュールの中まで見なくてもこれが役立たずだということがわかったわけですが……。
自分で書き直すならどうするかというと。
オブジェクト指向設計的に、パスワードオブジェクトの生成メソッドを作ってバリデーションをその中で持たせます。ただし、長さや文字の種類を見るくらいです。過去のパスワードとの重複チェックは別に書きます。そうしないと重複したパスワードがコンテキストの中で生成できませんからね。
パスワード要件は将来的に変化する可能性があるので、パスワードオブジェクト自体は文字列を何でも持てるようにします。最低限中身がイミュータブルでnullじゃないことを保証するところ。