Bối cảnh: Tôi đang phát triển một khung nhắn tin. Khung này sẽ cho phép:
- gửi tin nhắn qua xe buýt dịch vụ
- đăng ký hàng đợi trên xe buýt tin nhắn
- đăng ký chủ đề trên xe buýt tin nhắn
Chúng tôi hiện đang sử dụng RabbitMQ, nhưng tôi biết rằng chúng tôi sẽ chuyển sang Microsoft Service Bus (trên tiền đề) trong tương lai rất gần.
Tôi dự định tạo một bộ giao diện và triển khai để khi chúng tôi chuyển sang ServiceBus, tôi chỉ cần cung cấp một triển khai mới mà không sửa đổi bất kỳ mã khách hàng nào (ví dụ: nhà xuất bản hoặc người đăng ký).
Vấn đề ở đây là RabbitMQ và ServiceBus không thể dịch trực tiếp. Ví dụ: RabbitMQ dựa trên Trao đổi và Tên chủ đề, trong khi ServiceBus là tất cả về Không gian tên và Hàng đợi. Ngoài ra, không có giao diện chung giữa máy khách ServiceBus và máy khách RabbitMQ (ví dụ: cả hai có thể có kết nối IC, nhưng giao diện khác nhau - không phải từ một không gian tên chung).
Vì vậy, theo quan điểm của tôi, tôi có thể tạo một giao diện như sau:
public interface IMessageReceiver{
void AddSubscription(ISubscription subscriptionDetails)
}
Do các thuộc tính không thể dịch của hai công nghệ, việc triển khai ServiceBus và RabbitMQ của giao diện trên có các yêu cầu khác nhau. Vì vậy, ẩn ý RabbitMq của tôi về IMessageReceiver có thể giống như thế này:
public void AddSubscription(ISubscription subscriptionDetails){
if(!subscriptionDetails is RabbitMqSubscriptionDetails){
// I have a problem!
}
}
Đối với tôi, dòng trên phá vỡ quy tắc thay thế của Liskov.
Tôi đã cân nhắc việc lật nó xung quanh, để Đăng ký chấp nhận IMessageConnection, nhưng một lần nữa, Đăng ký RabbitMq sẽ yêu cầu các thuộc tính cụ thể của RabbitMQMessageConnection.
Vì vậy, câu hỏi của tôi là:
- Tôi có đúng rằng điều này phá vỡ LSP?
- Chúng ta có đồng ý rằng trong một số trường hợp, điều đó là không thể tránh khỏi, hoặc, tôi có đang thiếu thứ gì không?
Hy vọng, điều này là rõ ràng và về chủ đề!
interface IMessageReceiver<T extends ISubscription>{void AddSubscription(T subscriptionDetails); }
. Một triển khai sau đó có thể trông giống như public class RabbitMqMessageReceiver implements IMessageReceiver<RabbitMqSubscriptionDetails> { public void AddSubscription(RabbitMqSubscriptionDetails subscriptionDetails){} }
(trong java).
interface TestInterface<T extends ISubscription>
sẽ truyền đạt rõ ràng loại nào được chấp nhận và có sự khác biệt giữa các lần triển khai.