ドメインエキスパートの知識をコードに落とし込む:ビジネス概念の活用
この記事は、ChatGPTと自分の考えについて会話をした上で、ChatGPTに草稿を書いてもらったものです。(第三弾)
私は「ビジネス概念」という言葉を、ドメイン駆動設計(DDD)の中心的な考え方として提唱しています。この造語は、エンティティや値オブジェクトといった既存の分類にとらわれず、ドメインエキスパートの頭の中にあるビジネス知識そのものをコードに表現するためのアプローチを指します。
この記事では、ドメインエキスパートの知識を引き出し、それをビジネス概念として実装するプロセスとその意義について説明します。
ビジネス概念とは何か?
ビジネス概念とは、ビジネスエキスパートが持つ知識をシステム内で直接表現するための単位です。たとえば、「顧客ランク」「在庫有効期限」「発注点」など、業務において重要な概念が該当します。これらの概念は、単なるデータ構造ではなく、ビジネスルールや業務知識を含んだものとして設計されます。
このアプローチの鍵は、ドメインエキスパートとの対話にあります。彼らの知識を深く理解し、それをコードに反映することで、システムの意図と実装を一致させることが可能になります。
ビジネス概念をコードに落とし込む意義
1. ドメインエキスパートの知識を明文化
多くの場合、ビジネスの重要なルールや知識はエキスパートの頭の中に存在し、明文化されていません。ビジネス概念として実装することで、これらの知識を共有可能な形に変えることができます。
2. 業務ロジックの一貫性を保証
ビジネス概念をコードとして定義することで、システム全体で同じルールが適用され、一貫性が保たれます。これにより、誤った処理やルール違反を未然に防ぐことができます。
3. メンテナンス性と拡張性の向上
明確に定義されたビジネス概念は、コードの可読性を高めるだけでなく、新しい要件への対応を容易にします。責務が分離されているため、特定のルールや仕様を変更する際の影響範囲を限定できます。
ビジネス概念の実装例
以下は、「発注点(ReorderPoint)」というビジネス概念を表現した例です:
final class ReorderPoint
{
private int $value;
public function __construct(int $value)
{
if ($value < 0) {
throw new InvalidArgumentException("Reorder point cannot be negative");
}
$this->value = $value;
}
public function getValue(): int
{
return $this->value;
}
public function isBelow(int $stockQuantity): bool
{
return $stockQuantity < $this->value;
}
public function __toString(): string
{
return (string)$this->value;
}
このクラスは、発注点のルール(負の値を許容しない)を含み、在庫管理システムで重要な判断を直接コードで表現しています。
ドメインエキスパートとの対話を通じたビジネス概念の抽出
ビジネス概念を特定し、実装するためには、ドメインエキスパートとの綿密な対話が不可欠です。その際、以下の質問を投げかけることで、重要な知識を引き出すことができます:
- この業務で最も重要な判断基準は何ですか?
- どのようなルールが適用されますか?
- 日常的にどのような問題や課題が発生しますか?
たとえば、「発注点」は在庫管理において頻繁に議論される概念です。エキスパートに具体的な条件やルールを確認し、それをコードに変換することで、システム全体の信頼性を向上させることができます。
ビジネス概念とDDDの統合
ビジネス概念は、DDDの基本構造であるエンティティや値オブジェクトを補完する形で利用できます。
エンティティと値オブジェクトの役割
- エンティティ: ビジネス概念を組み合わせ、システム内で一意性を持つ複雑な構造体。
- 値オブジェクト: 単一のビジネス概念をそのまま表現し、再利用可能な部品として機能。
以下に、InventoryItem
エンティティがReorderPoint
を利用する例を示します:
final class InventoryItem
{
private string $itemCode;
private int $stockQuantity;
private ReorderPoint $reorderPoint;
public function __construct(string $itemCode, int $stockQuantity, ReorderPoint $reorderPoint)
{
$this->itemCode = $itemCode;
$this->stockQuantity = $stockQuantity;
$this->reorderPoint = $reorderPoint;
}
public function needsRestock(): bool
{
return $this->reorderPoint->isBelow($this->stockQuantity);
}
}
この設計では、発注点に関する業務ロジックをReorderPoint
クラスに委譲することで、InventoryItem
クラスの責務を明確化しています。
まとめ
ビジネス概念をコードに落とし込むことで、ドメインエキスパートの知識をそのままシステムに反映させることが可能になります。このアプローチは、DDDやクリーンアーキテクチャの原則をさらに強化し、より直感的で効果的な設計を実現します。
この手法を採用することで、開発者とビジネスエキスパートがより緊密に連携し、実際の業務ニーズに即したシステムを構築することができます。