0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

DDDのDomainServiceについて学びます。

DomainServiceとは

ドメイン駆動設計(DDD)において、特定のエンティティや値オブジェクトに属さないビジネスロジックをカプセル化するために使用される概念です。ドメインサービスは、エンティティや値オブジェクトでは表現しづらい操作やビジネスルールを実現するためのものです。

ドメインサービスの特徴

・エンティティに属さないロジック
複数のエンティティやアグリゲートにまたがるビジネスロジックや、エンティティに直接関連しないロジックを実装します。

・ステートレス:
通常、状態を持ちません。必要なデータはメソッドの引数として渡されます。これにより、再利用性が高まります。

・ビジネスロジックの集中:
ドメインサービスは、ビジネスロジックを一箇所に集中させることで、コードの可読性と保守性を向上させます。

具体例:eコマースシステムにおけるドメインサービス

・シナリオ
顧客がカートに商品を追加する際に、特定の割引を適用するロジックを実装します。この割引ロジックは、カートや商品エンティティに直接関連しないため、ドメインサービスとして実装するのが適しています。

エンティティと値オブジェクトの定義
class Product {
  constructor(
    private id: string,
    private price: number
  ) {}

  get productId() {
    return this.id;
  }

  get productPrice() {
    return this.price;
  }
}

class CartItem {
  constructor(
    private product: Product,
    private quantity: number
  ) {}

  get itemTotal() {
    return this.product.productPrice * this.quantity;
  }

  get details() {
    return {
      productId: this.product.productId,
      quantity: this.quantity,
      total: this.itemTotal,
    };
  }
}

class Cart {
  private items: CartItem[] = [];

  addItem(product: Product, quantity: number) {
    const item = new CartItem(product, quantity);
    this.items.push(item);
  }

  get cartItems() {
    return this.items.map(item => item.details);
  }
}
ドメインサービスの定義
class DiscountService {
  applyDiscount(cart: Cart, discountRate: number): number {
    const totalAmount = cart.cartItems.reduce((total, item) => total + item.total, 0);
    return totalAmount * (1 - discountRate);
  }
}
使用例
const product1 = new Product('product-1', 100);
const product2 = new Product('product-2', 200);

const cart = new Cart();
cart.addItem(product1, 2); // 2 items of product-1
cart.addItem(product2, 1); // 1 item of product-2

const discountService = new DiscountService();
const totalAfterDiscount = discountService.applyDiscount(cart, 0.1); // 10% discount

console.log(cart.cartItems);
// Output: [{ productId: 'product-1', quantity: 2, total: 200 }, { productId: 'product-2', quantity: 1, total: 200 }]
console.log(totalAfterDiscount);
// Output: 360 (10% discount applied to total of 400)

ドメインサービスのポイント

・再利用性: ドメインサービスを使用することで、ビジネスロジックを複数のエンティティから切り離し、再利用しやすくなります。
・シンプルさ: エンティティ自体をシンプルに保ち、エンティティに直接関係しないロジックを別のクラスに切り出すことで、コードの可読性と保守性を高めます。
・一貫性: ビジネスロジックを一箇所に集中させることで、一貫したルールの適用を保証します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?