における、「ドメインオブジェクト」(ないし、ドメイン)の説明が個人的にとても分かりやすかった。
そこで、当書とは別の題材を例に「ドメインオブジェクト」の文脈の解説を試みる。
「郵便番号」をプログラムで扱うこと考える
「郵便番号」は次のような概念を持っている。
- 7けた
- 3けた目と4けた目の間にハイフンを入れる
- 旧郵便番号に従う3けたもしくは5けたの「郵便区番号」と、それぞれ4けたもしくは2けたの「町域番号」からなる
―― 日本郵政HP https://www.post.japanpost.jp/zipcode/zipmanual/p04.html より2021年10月2日現在
プログラムで扱うことを考えると、ハイフンを含めて8文字の文字列であるから愚直に ↓ のように書くこともできる。
String zipCode = "350-1106";
しかし、このように扱うといくつか問題が出てくる。
① ハイフンを含むのか含まないのか使う側で意識する必要がある
/**
* 郵便番号からお届け日数を算出する
* @param 郵便番号
* @return お届け日数
*/
int calculateDeliveryDays(String zipCode) [
// zipCode が ハイフンを含むのか、含まないのかを意識する必要がある
}
② けた数間違いや番号の妥当性を都度検査する必要がある
String zipCode = "350-1106";
// けた数の検査
if (zipCode.replace("-", "").length() != 7) {
throw new IllegalArgumentException("郵便番号のけた数が不正です");
}
③ 郵便番号から郵便区番号や町域番号を取り出す同じような処理が散らばる
String zipCode1 = "350-1106";
String zipSectionCode1 = zipCode.replace("-", "").substring(0, 5)
// zipSectionCode1 を使う処理
String zipCode2 = "163-8001";
String zipSectionCode2 = zipCode.replace("-", "").substring(0, 5)
// zipSectionCode2 を使う処理
「郵便番号」クラスで諸問題を解決する
class ZipCode {
static final int ZIP_CODE_LENGTH = 7;
static final int HYPHEN_SEPARATED_INDEX = 3;
static final int ZIP_SECTION_CODE_LENGTH = 5;
String withHyphen; // 利用者側はよしなに使い分けられる(①を解決)
String withoutHyphen; // 利用者側はよしなに使い分けられる(①を解決)
ZipCode(String value) {
withoutHyphen = value.replace("-", "");
withHyphen = value.insert(HYPHEN_SEPARATED_INDEX, "-");
if (withoutHyphen.length() != ZIP_CODE_LENGTH) {
throw new IllegalArgumentException("郵便番号のけた数が不正です"); // インスタンス生成時に桁数を検査(②を解決)
}
}
/**
* 郵便区番号を取得する
* @return 郵便区番号
*/
String getZipSectionCode() {
return withoutHyphen.substring(0, ZIP_SECTION_CODE_LENGTH) // メソッドを共通化(③を解決)
}
}
※ これはあくまで例で、厳密には郵便区番号は3けたの場合があったり、番号の妥当性を検査する必要がある。
「郵便番号」クラスはドメインオブジェクト
「郵便番号」クラスのように、業務で使われる用語に合わせて、その用語の関心事に対応するクラスをドメインオブジェクトと呼ぶ。
DDDにおける、アプリケーションの対象領域(ドメイン)の関心事を記述したオブジェクトという意味だ。
ご意見ご感想等ございましたら、コメントお願いします