[Spring] Factory Pattern을 활용한 Service 관리2

taeni·2023년 3월 21일
0

Factory Pattern을 활용한 Service 관리2

아래 코드는 pattern을 설명하기 위한 예시이므로 로직상에 어색함이 있을 수 있다.

Abstract class

@RequiredArgsConstructor
abstract class OrderService {
	private final UserDao userDao;
	
    abstract ProductType getProductType;
	abstract int getPoint(String productCode);
    abstract int getProductName(String productCode);
    
    public void order(Order order) {
    	orderDao.insertOrderTemp(order);
    
    	int point = getPoint(order.getProductCode());
        String productName = getProductName(order.getProductCode());
                
		order.setPorint(point);
        order.setProductName(productName);
        
        requestOrder(order);
    }
    
    private void validOrder(Order order) throws OrderException {
    	// 주문 정보 유효성 체크
    }
    
    private void requestOrder(Order order) {
    	// 주문 실행
    }
}

옷 주문 Service

@Service
public ClothesOrderService extends OrderService {
	private final ClothesProductDao clothesProductDao;
	public ClothesOrderService(UserDao userDao, ClothesProductDao clothesProductDao) {
    	super(userDao);
        this.clothesProductDao = clothesProductDao;
    }
    
    @Override
    ProductType getProductType() {
    	return ProductType.Clothes;
    }

	@Override
	int getPoint(String productCode) {
    	// 포인트 계산 로직
        
		return 포인트;
    }
    
    @Override
    int getProductName(String productCode) {
    	// 상품명 조합 로직
        
		return 상품명;
    }
}

식품 주문 Service

@Service
public FoodOrderService extends OrderService {
	private final FoodProductDao foodProductDao;
	public ClothesOrderService(UserDao userDao, FoodProductDao foodProductDao) {
    	super(userDao);
        this.foodProductDao = foodProductDao;
    }
	
    @Override
    ProductType getProductType() {
    	return ProductType.Food;
    }


	@Override
	int getPoint(String productCode) {
    	// 포인트 계산 로직
        
		return 포인트;
    }
    
    @Override
    int getProductName(String productCode) {
    	// 상품명 조합 로직
        
		return 상품명;
    }
}

주문 Service Factory

@Component
public class OrderServiceFactory {
	private final Map<ProductType, OrderService> orderServiceMap = new HashMap<>();
    
    public OrderServiceFactory(List<OrderService> orderServices) {
    	orderServices.forEach(s -> orderServiceMap.put(s.getOrderType(), s);
    }
    
    public OrderService getOrderService(ProductType productType) {
		return orderServiceMap.get(productType);
	}   
}

주문 Service Factory 사용

@RequiredArgsConstructor
@RestController
public class OrderController {
	private final ModelMapper modelMapper;
	private final OrderServiceFactory orderServiceFactory;
	
    @PostMapping("/order")
    public ResponseEntity order(@RequestBody OrderDto.Request requestDto) {
    	Order order = modelMapper.map(requestDto, Order.class);
        orderServiceFactory.getOrderService(requestDto.getProductType()).order(order);
        
        return ResponseEntity.ok();
    }
}
profile
정태인의 블로그

0개의 댓글