티스토리 뷰

들어가며

전략 패턴 정의는 각각의 알고리즘 군을 교환이 가능하도록 별도로 정의하고 각각 캡슐화한 후 서로 교환해서 사용할 수 있는 패턴이다. 이 패턴을 적용시키기 위해서 회원 정보와 결제 정보를 외부에 요청을 보내는 서비스에 적용해보았다. 또한 제네릭을 통해 각각 VO 객체를 보낼 수 있도록 유연함도 추가하였다. 큰 구조로 보면 요청을 보내는 인터페이스와 각각 전략을 넣을 수 있는 구현 클래스들로 구성된다.

코드 설계

GateRequestService.java

public interface GateRequestService<T> {
    void request(T object);
}
  • 외부에 요청을 보내는 메서드 생성
  • 제네릭 vo 객체를 받을 수 있도록 설정


GateRequestSignUpService.java
GateRequestOrderService.java

@Service("gateRequestSignUpService")
@RequiredArgsConstructor
public class GateRequestSignUpService implements GateRequestService<Account> {

    private final GateApiClient gateApiClient;

    @Override
    public void request(Account account) {

        // 회원 유효성 체크
        ...

        // 외부 요청
        gateApiClient.post(account);
    }
}


@Service("gateRequestOrderService")
@RequiredArgsConstructor
public class GateRequestOrderService implements GateRequestService<Orders> {

    private final GateApiClient gateApiClient;

    @Override
    public void request(Orders orders) {

        // 주문 유효성 체크
        ...

        // 외부 요청
        gateApiClient.post(orders);
    }
}
  • 각 구현 클래스의 빈을 식별하기 위해 카멜 케이스로 빈 이름 등록
  • GateRequestService.request 상속받은 후 제네릭 안에 객체 주입
  • 각각 전략에 맞게 유효성 체크(회원, 주문)
  • 외부에 요청할 수 있는 GateApiClient 주입 받은 후 post 요청


AccountController.java

@Controller
@RequiredArgsConstructor
public class AccountController {

    @Resource(name = "gateRequestSignUpService")
    private final GateRequestService<Account> gateRequestService;
    private final AccountService accountService;

    @PostMapping("/account/signup")
    public ResponseEntity<boolean> postSignup(@RequestBody Account account) {
        
        gateRequestService.request(account)
        
        return ResponseEntity.ok(accountService.postSignup(account));
    }
}


@Controller
@RequiredArgsConstructor
public class OrdersController {

    @Resource(name = "gateRequestOrdersService")
    private final GateRequestService<Orders> gateRequestService;
    private final OrdersService ordersSerivce;

    @PostMapping("/orders")
    public ResponseEntity<boolean> postOrders(@RequestBody Orders orders) {
        
        gateRequestService.request(orders)
        
        return ResponseEntity.ok(ordersSerivce.postOrders(orders));
    }
}
  • GateRequestService의 구현 클래스를 식별할 수 있게 @Resource 어노테이션을 통해 주입
    - GateRequestService -> 회원 데이터 -> GateRequestSignUpService
    - GateRequestService -> 주문 데이터 -> GateRequestOrderService
  • 각 구현 클래스의 vo 객체를 받을 수 있게 객체 주입



결론

인터페이스 목적인 어떤 요청이 왔을 때 그 요청이 필요한 서비스를 찾아주는 것으로 흔히 많이 쓰는 JPA의 Querydsl는 큰 Querydsl 안에 구현 클래스 중에 하나이다. 같은 맥락으로 큰 GateRequestService 인터페이스 안에 GateRequestSignupService와 GateRequestOrdersService로 나뉘게 된다. 이렇게 함으로써 OCP 원칙도 지킬 수 있으며 다른 외부 요청에 보내야 하는 상황이 오면 구현 클래스를 하나 더 생성을 통해 유연함을 가지게 된다.

'∙디자인패턴' 카테고리의 다른 글

[디자인패턴] 팩토리 패턴(Factory Pattern)  (0) 2024.05.29