はじめに
最近セキュア・バイ・デザイン 安全なソフトウェア設計(以下、セキュア・バイ・デザイン)を読んだので、学んだことをアウトプットしようと思います。
今回は特に印象に残ったドメインプリミティブについてです。
ドメインプリミティブとは
セキュア・バイ・デザインで紹介されている実装パターンのことです。
バリューオブジェクトとよく似ていますが、似て非なるものになります。
ドメインプリミティブはバリューオブジェクトの特性を持ちつつ、さらに以下の特性があります。
- プログラミング言語における基本データ型やStringなどのような汎用的な型を使用しない
- Nullを許容しない
- 不変条件をオブジェクトの生成時に確認する
不変条件とは
ドメインが持つ何が起きても変わることのない特性のことを不変条件といいます。
- 年齢の場合
- Nullでないこと
- 整数であること
- 0から150の間であること(150は人類最高齢が122なのでそこから余裕持った値)
- 携帯電話番号の場合
- Nullでないこと
- 070,080,090のいずれかから始まること
- 11桁の整数であること
上記のような条件をドメインに持たせることにより、よりセキュアなオブジェクトを生成することができるようになります。
不変条件は、ドメインエキスパートなどとしっかり話し合ってドメインを深く理解することで見えてきます。
型や桁数、受け入れるべき文字の種類など細かいところまでしっかりと話すことが大事です。
ドメインプリミティブとバリューオブジェクトの違い
実際にコードでドメインプリミティブとバリューオブジェクトを比較してみます。
今回は年齢をお題としてやってみます。
バリューオブジェクト
public record Age(Integer value) {}
ドメインプリミティブ
public record Age(Integer value) {
public Age { //コンパクトコンストラクタで生成前にチェック
if(Objects.isNull(value)) throw new IllegalArgumentException("値がNullです");
if(value < 0 || value > 150) { // 0から150歳まで
throw new IllegalArgumentException("値が不正です");
}
}
}
上記のように、ドメインプリミティブではNullのチェックや年齢として扱える数値の範囲を表現しています。
これにより、ドメインプリミティブでAgeというクラスが生成された際に、0から150の値が入っていることが保証されます。
そのため、呼び出し元でNullのチェックや、代入されている値の妥当性を確認する必要がなくなるのです。
セキュアなドメインを生成することで、コードの不正確さや曖昧さ、エラーの起こりやすさなどを防ぐことができます。
さいごに
今回はドメインプリミティブについて簡単にですがまとめました。
システムを構築する上で、たくさんのドメインを取り扱うと思います。
その1つ1つをしっかり定義づけして、ドメインプリミティブに落としていくことでとてもセキュアでわかりやすいシステムになると思いました。
ドメインプリミティブはセキュア・バイ・デザインのプラクティスの中でも非常に取り入れやすいので、取っ掛かりとして良いと思います。
また、この本はこれ以外にも非常に勉強になることが書いてあるので、まだの方はぜひ読んでみてください。