はじめに
DDDを学んでいく上でユビキタス言語というワードがあります。
ちょっと調べてみると、ユビキタス言語とは「サービスのターゲット業務や開発に関わるすべての人が、見聞きして同じ意図を連想できる一意の言葉」のようです。
「なるほどなぁ」と実際の業務でも確かに同じような事を無意識的にやっています。
ただ、ユビキタス言語をコードにちゃんと表現していくのが大事なんだろうなぁと思い、コードに落とし込む事をやっていきたいと思います。
ユビキタス言語の目的
プロジェクト全体で一貫した用語を使用することで、コミュニケーションの障壁を取り除き、誤解を減らし、ソフトウェアの品質を向上させることを目的としています。
コードに落とし込む(eコマースのドメインを例に)
ユビキタス言語の用語
・カート (Cart)
ユーザーが購入を検討している商品を一時的に保存する場所。
・商品 (Product)
eコマースサイトで販売されているアイテム。
・注文 (Order)
ユーザーがカート内の商品を購入するために確定した情報のセット。
・顧客 (Customer)
サイトを利用して商品を購入する人。
・在庫 (Inventory)
商品の保管場所や数量を管理するシステム。
・支払い (Payment)
商品購入に対する金銭のやり取り。
ドメイン専門家と開発者の会話
ドメイン専門家: 「顧客がカートに商品を追加するプロセスを改善したいです。カートに商品が追加された時点で在庫の数をチェックして、在庫が足りない場合は警告メッセージを表示したいです。」
開発者: 「了解しました。カートに addProductToCart メソッドを追加して、商品が追加されるたびに Inventory サービスを呼び出して在庫を確認します。もし在庫が足りない場合は、 InsufficientInventoryException をスローして警告メッセージを表示します。」
プログラム
// 商品エンティティ
class Product {
constructor(
private id: string,
private name: string,
private price: number
) {}
get productId() {
return this.id;
}
}
// カートエンティティ
class Cart {
private items: Map<string, number> = new Map();
constructor(private inventoryService: InventoryService) {}
addProductToCart(product: Product, quantity: number) {
if (this.inventoryService.isAvailable(product.productId, quantity)) {
const currentQuantity = this.items.get(product.productId) || 0;
this.items.set(product.productId, currentQuantity + quantity);
} else {
throw new Error('InsufficientInventoryException');
}
}
get cartItems() {
return Array.from(this.items.entries()).map(([productId, quantity]) => ({
productId,
quantity,
}));
}
}
// 在庫サービス
class InventoryService {
private stock: Map<string, number> = new Map();
isAvailable(productId: string, quantity: number): boolean {
const availableStock = this.stock.get(productId) || 0;
return availableStock >= quantity;
}
// 在庫を追加するメソッド(例として)
addStock(productId: string, quantity: number) {
const currentStock = this.stock.get(productId) || 0;
this.stock.set(productId, currentStock + quantity);
}
}
// 使用例
const inventoryService = new InventoryService();
inventoryService.addStock('product-1', 10);
const cart = new Cart(inventoryService);
const product = new Product('product-1', 'Sample Product', 100);
cart.addProductToCart(product, 2);
console.log(cart.cartItems);
// Output: [{ productId: 'product-1', quantity: 2 }]
ユビキタス言語の重要性
一貫性: プロジェクト全体で統一された用語を使うことで、開発者とビジネス側との間で一貫した理解が得られます。
明確なコミュニケーション: 誤解を減らし、明確なコミュニケーションを促進します。
ドキュメントとしてのコード: コード自体がドキュメントの役割を果たし、誰が見ても理解しやすくなります。
(なるほどね。確かにドキュメントとしてのコードって保守開発する上ですごい重要。なるほどなぁ。。。)