이번 글에서는 유즈케이스에 대해 작성해보겠습니다.
유즈케이스는 시스템이 사용자와 상호작용하는 방식을 설명하는 방법입니다. 이는 특정 목표를 달성하기 위해 사용자가 시스템과 어떻게 상호작용하는지를 정의합니다. 유즈케이스는 주로 사용자의 요구사항을 이해하고, 시스템의 기능을 명확히 하는 데 도움을 줍니다. 각 유즈케이스는 하나의 비즈니스 로직을 담고 있습니다. 예를 들어, 사용자 등록, 로그인, 주문 처리 등의 기능이 포함됩니다.
유즈케이스는 일반적으로 다음과 같은 요소로 구성됩니다
Repository 패턴을 예로 들면, Repository로부터 얻은 행위자(도메인)로 시나리오(비즈니스 로직)를 진행하여 목표를 충족한다고 생각합니다.
다음은 이해를 돕기 위한 제품 주문 생성을 위한 유즈케이스 코드입니다.
struct Product {
let id: Int
let name: String
let price: Double
}
struct Order {
let id: Int
let products: [Product]
let totalAmount: Double
}
protocol ProductRepository {
func getProduct(by id: Int) -> Product?
}
protocol OrderRepository {
func getOrdersCount() -> Int
func saveOrder(_ order: Order)
}
class InMemoryProductRepository: ProductRepository {
private var products: [Int: Product] = [
1: Product(id: 1, name: "상품 A", price: 100.0),
2: Product(id: 2, name: "상품 B", price: 200.0)
]
func getProduct(by id: Int) -> Product? {
return products[id]
}
}
class InMemoryOrderRepository: OrderRepository {
private var orders: [Order] = []
func getOrdersCount() -> Int {
return orders.count
}
func saveOrder(_ order: Order) {
orders.append(order)
print("주문이 저장되었습니다: \(order)")
}
}
class CreateOrderUseCase {
private let productRepository: ProductRepository // DIP 원칙
private let orderRepository: OrderRepository
init(productRepository: ProductRepository, orderRepository: OrderRepository) {
self.productRepository = productRepository
self.orderRepository = orderRepository
}
func execute(productIds: [Int]) {
var orderedProducts: [Product] = []
var totalAmount: Double = 0.0
for productId in productIds {
if let product = productRepository.getProduct(by: productId) {
orderedProducts.append(product)
totalAmount += product.price
} else {
print("상품 ID \(productId)는 유효하지 않습니다.")
}
}
if !orderedProducts.isEmpty {
let orderCount = orderRepository.getOrdersCount()
let order = Order(id: orderCount + 1, products: orderedProducts, totalAmount: totalAmount)
orderRepository.saveOrder(order)
} else {
print("주문할 상품이 없습니다.")
}
}
}
let productRepository: ProductRepository = InMemoryProductRepository()
let orderRepository: OrderRepository = InMemoryOrderRepository()
let createOrderUseCase = CreateOrderUseCase(productRepository: productRepository, orderRepository: orderRepository)
// 주문 생성
createOrderUseCase.execute(productIds: [1, 2]) // 상품 A와 상품 B를 주문
createOrderUseCase.execute(productIds: [3]) // 유효하지 않은 상품 ID
/*
출력 결과:
주문이 저장되었습니다: Order(id: 1, products: [Product(id: 1, name: "상품 A", price: 100.0), Product(id: 2, name: "상품 B", price: 200.0)], totalAmount: 300.0)
상품 ID 3는 유효하지 않습니다.
주문할 상품이 없습니다.
*/
위의 코드를 요약하면 도메인 모델인 Product와 Order를 정의하여 상품과 주문의 속성을 나타내고 리포지토리를 정의하여 상품과 주문을 관리합니다. 이후 유즈케이스를 통해 상품 ID를 받아 주문을 생성하는 비즈니스 로직을 구현합니다.