sync product license using delegation pattern

2023, Jul 03    

문제 상황

  • 중앙 어플리케이션에서 갖고 있는 라이선스 정보에 맞게 허용여부를 체크해야한다.
  • 라이선스를 중앙에서 관리하는 시스템이 부재한 상태
  • API 스펙이 변경될 때마다 대응개발을 해야하는 문제

의존성 해결을 위한 방법 모색

1안. 중앙 집중식 라이선스 관리 시스템 구축

  • 이 시스템을 통해 메인 어플리케이션과 클라이언트 간의 데이터 송수신을 관리하고, 라이선스 허용 여부를 결정하는 역할을 수행하게 한다.
  • 이렇게 구축된 중앙 집중식 라이선스 관리 시스템은 메인 어플리케이션과의 의존성을 줄여주며, 라이선스 API 스펙이 변경되더라도 시스템 내에서만 대응 개발을 하면 된다.
  • 또한, 라이선스 정보를 중앙에서 효율적으로 관리할 수 있으며, 다른 어플리케이션과의 통합도 용이하게 된다.

2안. Delegation 패턴 사용

  • Delegation 패턴을 사용하여 메인 어플리케이션에서 라이선스 관리를 별도의 객체 또는 모듈에 위임한다.
  • 이를 통해 메인 어플리케이션은 라이선스 관련 로직에 대한 직접적인 의존성을 줄일 수 있고,
  • 라이선스 관리 객체는 메인 어플리케이션으로부터 클라이언트 데이터를 받아 허용 여부를 판단하고, 허용된 데이터만 메인으로 전달한다.
  • 따라서 메인 어플리케이션은 라이선스 관련 변경이 발생하더라도, 라이선스 관리 객체의 인터페이스만을 준수하면 되므로 대응 개발이 용이해진다.

ℹ️ Delegation 패턴이란?

Delegation 패턴은 하나의 객체가 다른 객체에게 특정 동작을 위임하는 것을 의미한다.
이를 통해 객체 간의 결합도를 줄이고 코드의 재사용성과 확장성을 높일 수 있다.
  • Delegation 패턴 적용 설계
    • 라이선스 관리 객체 설계
      • 라이선스 관리에 필요한 기능을 수행할 라이선스 관리 객체를 설계
      • 이 객체는 메인 어플리케이션으로부터 클라이언트 데이터를 받아 허용 여부를 판단하고, 허용된 데이터만을 메인으로 전달하는 역할을 수행하게 한다.
    • 인터페이스 정의
      • 메인 어플리케이션과 라이선스 관리 객체 간의 인터페이스를 정의한다. 이를 통해 메인 어플리케이션은 라이선스 관리 객체의 기능을 호출할 수 있다. 인터페이스는 메인 어플리케이션의 요구에 맞게 설계되어야 한다.
    • Delegation 구현
      • 메인 어플리케이션은 라이선스 관리 객체를 생성하고, 자체적으로 수행하지 않을 라이선스 관련 작업을 해당 객체에 위임한다. 메인 어플리케이션은 라이선스 관리 객체를 통해 클라이언트 데이터의 허용 여부를 확인하고, 허용된 데이터만을 처리한다.
  • Delegation 패턴 적용 효과
    • 메인 어플리케이션과 라이선스 관리 기능 사이의 의존성을 줄일 수 있다.
    • 메인 어플리케이션은 라이선스 관리 객체의 인터페이스에만 의존하고, 라이선스 관리 객체의 구현 내용이 변경되더라도 메인 어플리케이션에는 영향을 주지 않게된다.
    • 이를 통해 유연하고 확장 가능한 코드를 작성할 수 있다.

3안. 클라이언트 사이드 라이선스 검증

  • 클라이언트 측에서 라이선스 검증 로직을 구현하여, 메인 어플리케이션으로 전송되는 데이터를 미리 필터링할 수 있다.
  • 클라이언트는 라이선스 정보를 가져와서 로컬에서 검증하고, 허용된 데이터만 메인 어플리케이션으로 전송한다.
  • 이 경우, 메인 어플리케이션에서는 단순히 검증된 데이터를 처리하기만 하면 되므로 라이선스 API 스펙의 변경에 덜 민감해진다는 장점이 있다.

이러한 대안적인 접근 방식은 중앙 집중식 라이선스 관리 시스템과 비교하여 일부 제약사항이 있을 수 있지만, 현재 스프린트에서 구현하기에 더 적합한 솔루션일 수 있다.

작업 방향

  • 메인 어플리케이션 의존성 최소화
  • API 변경 대응개발을 하지 않도록
  • 라이선스 json 구조에 대해 모르고 싶다.

작업 내용

AS-IS

  • 2안과 3안이 섞인 모습으로 동작하고 있었다.
    • 메인 어플리케이션의 라이선스 API의 리턴 모델 클래스를 클라이언트 서버에서도 갖고 있으면서 로직상 필요할 때마다 캐싱된 데이터를 기준으로 허용여부를 판단했다
    • API 스펙이 변경될 때마다, 대응개발이 발생

TO-BE

  • 라이선스가 별도의 어플리케이션으로 분리되면서 1안의 모습으로 구현이 가능해짐
  • API 리턴 모델 클래스 대신 Map으로 리턴되도록 스펙을 변경해서, 모델에 대한 의존성은 줄어들수 있었다.
  • 라이선스가 변경될 때 발행되는 kafka 이벤트를 수신해서 캐싱된 정보를 evict하는 부분은 그대로 유지