배경 : 메시징 프레임 워크를 개발 중입니다. 이 프레임 워크는 다음을 허용합니다.
- 서비스 버스를 통한 메시지 전송
- 메시지 버스의 대기열에 가입
- 메시지 버스의 주제 구독
현재 RabbitMQ를 사용하고 있지만 가까운 시일 내에 Microsoft Service Bus (Premise)로 전환 할 것입니다.
ServiceBus로 이동할 때 클라이언트 코드 (예 : 게시자 또는 구독자)를 수정하지 않고 새로운 구현을 제공하기 만하면되도록 일련의 인터페이스 및 구현을 만들 계획입니다.
여기서 문제는 RabbitMQ와 ServiceBus를 직접 번역 할 수 없다는 것입니다. 예를 들어 RabbitMQ는 Exchange와 주제 이름에 의존하는 반면 ServiceBus는 네임 스페이스와 대기열에 관한 것입니다. 또한 ServiceBus 클라이언트와 RabbitMQ 클라이언트 사이에 공통 인터페이스가 없습니다 (예 : 둘 다 IConnection이있을 수 있지만 인터페이스는 공통 네임 스페이스가 아님).
그래서 요점으로 다음과 같이 인터페이스를 만들 수 있습니다.
public interface IMessageReceiver{
void AddSubscription(ISubscription subscriptionDetails)
}
두 기술의 번역 할 수없는 특성으로 인해 위 인터페이스의 ServiceBus 및 RabbitMQ 구현에는 서로 다른 요구 사항이 있습니다. 따라서 IMessageReceiver의 RabbitMq 구현은 다음과 같습니다.
public void AddSubscription(ISubscription subscriptionDetails){
if(!subscriptionDetails is RabbitMqSubscriptionDetails){
// I have a problem!
}
}
나에게 위의 줄은 Liskov의 대체 가능성 규칙을 어 기고 있습니다.
서브 스크립 션이 IMessageConnection을 허용하도록이 문제를 뒤집는 것을 고려했지만 RabbitMq 서브 스크립 션은 RabbitMQMessageConnection의 특정 속성이 필요합니다.
그래서 내 질문은 :
- 이것이 LSP를 위반하는 것입니까?
- 어떤 경우에는 피할 수없는 것, 또는 뭔가 빠진 것에 동의합니까?
바라건대, 이것은 분명하고 주제입니다!
interface IMessageReceiver<T extends ISubscription>{void AddSubscription(T subscriptionDetails); }
. 제안하고 싶은 것은 입니다. 그러면 구현은 public class RabbitMqMessageReceiver implements IMessageReceiver<RabbitMqSubscriptionDetails> { public void AddSubscription(RabbitMqSubscriptionDetails subscriptionDetails){} }
(자바에서) 처럼 보일 수 있습니다.
interface TestInterface<T extends ISubscription>
어떤 유형이 허용되는지, 구현간에 차이가 있음을 명확하게 전달하는 것과 같은 것이 있습니다.