public 메소드로 변경하는 방법과 인터페이스를 정의하여 사용하는 방법의 차이

Gom·2023년 12월 31일
0

TypeScript

목록 보기
5/5

업로드중..

케이스 설명

주문이 이루어지면 재고가 차감되어야 하는 상황입니다.

productService 내부에 deductInventory 함수가 있습니다.
orderService에서 주문이 발생하면 재고를 차감해야 합니다.

서로 다른 Service 간 함수를 공유하는 3가지 방법

1. deductInventory를 Public 메소드로 둔다.

deductInventory 메소드를 ProductService 내부에서 public 메소드로 변경하고 OrderService에서 이를 호출합니다. 이 방법은 OrderService가 ProductService에 대한 의존성을 갖게 되며, 재고 관리 로직이 ProductService 내에 남아있게 됩니다.

// ProductService에 있는 deductInventory 메소드를 public으로 변경

public async deductInventory(
  entityManager: EntityManager,
  productId: number,
  quantity: number,
): Promise<void> {
  // 기존 로직 유지
}

// OrderService에서 ProductService의 deductInventory 사용
await this.productService.deductInventory(transactionalEntityManager, productId, quantity);

2. deductInventory를 공용 유틸리티로 분리한다.

deductInventory 로직을 별도의 공용 유틸리티 또는 서비스로 분리하고, 이를 OrderService와 ProductService에서 모두 사용합니다. 이 방법은 재고 관리 로직을 중앙화하고, 다양한 서비스에서 재사용할 수 있게 합니다.


// 별도의 유틸리티 또는 서비스 파일
export async function deductInventory(
  entityManager: EntityManager,
  productId: number,
  quantity: number,
): Promise<void> {
  // 기존 로직 유지
}

// OrderService와 ProductService에서 이 함수를 사용
await deductInventory(transactionalEntityManager, productId, quantity);

3. 인터페이스 사용

재고 관리와 관련된 인터페이스를 정의하고, ProductService가 이 인터페이스를 구현하게 합니다. 그런 다음 OrderService에서는 이 인터페이스를 사용하여 재고 관리를 수행합니다. 이 방법은 객체 지향 설계 원칙에 부합하며, 서비스 간의 결합도를 낮출 수 있습니다.


// 인터페이스 정의
interface InventoryManager {
  deductInventory(entityManager: EntityManager, productId: number, quantity: number): Promise<void>;
}

// ProductService가 인터페이스를 구현
class ProductService implements InventoryManager {
	async deductInventory(entityManager: EntityManager, productId: number, quantity: number): Promise<void> {
    // 여기에 실제 로직 구현
  }
}

// OrderService에서 인터페이스 사용
class OrderService {
  constructor(private inventoryManager: InventoryManager) {}

  // ...
  await this.inventoryManager.deductInventory(transactionalEntityManager, productId, quantity);
}

각 접근 방식은 특정 상황과 프로젝트 요구 사항에 따라 장단점을 가지므로,
프로젝트의 아키텍처와 유지보수성을 고려하여 선택하는 것이 중요합니다.

public 메소드로 변경하는 방법과 인터페이스를 정의하여 사용하는 방법의 차이

1. Public 메소드로 변경하는 방법

ProductService의 메소드를 public으로 만들고 이를 OrderService에서 직접 호출하는 경우를 생각해 보겠습니다. 이 방법은 마치 레스토랑에서 웨이터를 통해 주방장에게 직접 요리를 주문하는 것과 비슷합니다. 웨이터(OrderService)는 주방장(ProductService)이 어떻게 요리를 하는지 정확히 알 필요는 없습니다. 웨이터는 메뉴(메소드)를 보고 주문(함수 호출)만 하면 됩니다.

장점: 직접적이고 간단합니다. 주방장의 요리 방법을 알 필요 없이 메뉴를 통해 요리를 주문할 수 있습니다.
단점: 웨이터는 주방장이 바뀌면 메뉴가 바뀔 수 있음을 알아야 합니다. 즉, ProductService의 구현이 바뀌면 OrderService도 영향을 받을 수 있습니다.

2. 인터페이스를 정의하여 사용하는 방법

인터페이스를 사용하는 방법은 마치 레스토랑이 여러 주방장(서비스) 사이에서 공통된 요리 방법(인터페이스)을 정의하는 것과 비슷합니다. 여기서 웨이터(OrderService)는 특정 주방장(ProductService)에 직접 의존하는 것이 아니라, 레스토랑이 정한 요리 방법(인터페이스)에 따라 주문합니다. 이렇게 하면 주방장이 바뀌어도 요리 방법이 같기 때문에 웨이터는 영향을 받지 않습니다.

장점: 유연성과 확장성이 뛰어납니다. 새로운 주방장이 와도 동일한 요리 방법(인터페이스)을 따르기 때문에 웨이터는 영향을 받지 않습니다.

단점: 요리 방법(인터페이스)을 정의하고 관리해야 하는 추가적인 작업이 필요합니다.설계가 조금 더 복잡해지며, 새로운 인터페이스와 클래스를 추가해야 할 수 있습니다.

차이점

직접성 vs 추상성:
Public 메소드로 변경하는 방법은 더 직접적이고 구체적입니다. 반면 인터페이스를 사용하는 방법은 더 추상적이며 유연합니다.

의존성:
Public 메소드를 사용하면 OrderService가 ProductService의 구체적인 구현에 의존하게 됩니다. 인터페이스를 사용하면 이러한 의존성을 인터페이스라는 추상적인 계층으로 옮겨 느슨하게 만들 수 있습니다.

변경 관리:
ProductService가 변경되어도 인터페이스를 사용하는 방법이 OrderService에 미치는 영향을 최소화할 수 있습니다.

간단히 말해, Public 메소드로 변경하는 것은 빠르고 쉽지만, 장기적으로는 인터페이스를 사용하는 것이 더 나은 설계 결정을 유도하고, 유지보수와 확장성 측면에서 이점을 제공할 수 있습니다.

profile
안 되는 이유보다 가능한 방법을 찾을래요

0개의 댓글