不変でビルダーパターンを使用して作成されたCar
モデルオブジェクト(として)を想定します。case class
(Joshua Bloch によるビルダー パターン)。
そのbuild
メソッドは、CarValidator
関連する の作成を許可するかどうかを許可するために、オブジェクトを呼び出しますCar
。それ以外の場合は、IllegalStateException
予期しないフィールドが正確に指定された がスローされます。
Car
したがって、実行時にいつでも古いまたは無効なものを作成することはできませんでした。
を作成する Web フォームがあるとしますCar
。Play のコントローラーには、次のフォーム マッピングが含まれます。
val carForm = Form( //this is a conceptual sample
mapping(
"brand" -> nonEmptyText,
"description" -> nonEmptyText,
"maxSpeed" -> number
"complexElement" -> number.verifying(........) //redundant validation here
)(Car.apply)(Car.unapply)
)
この例ではいくつかの基本的なフィールドがありますが、ここのような複雑なビジネス検証を必要とするより複雑なフィールドを想像してみてcomplexeElement
ください。
DRY(Don't Repeat Yourself)は簡単に破れそうな予感がします。
実際、フォームの検証がもたらすものは何でも、Car
モデルの検証は最も重要な検証場所であり、他のものに依存するべきではないため、これはビルダーのバリデーターによって既に提供されています。
ビルダーが使用するのと同じバリデーターオブジェクトを扱うHelper
クラスに近いソリューションを想像します。Controller
ただし、Web フォームの任意の検証ステップで個別に呼び出すために、すべての検証メソッドを取得public
する必要があります (上記のコード スニペットのように)。
DRY を破らないようにしながら、このビルダーの原則を維持するための良い方法は何でしょうか?