首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多通道通知系统- LLD -

多通道通知系统- LLD -
EN

Stack Overflow用户
提问于 2022-07-22 10:30:18
回答 1查看 95关注 0票数 0

您必须设计类来构建一个支持多种渠道的通知系统,如电子邮件、SMS、Whatsapp。它应该容易扩展。

My设计:

代码语言:javascript
复制
class Message {
NotificationType type ; //email, sms
msgId;
String content ;
}
MessagingServiceImpl {
static {
//map from notification type to the respective handler
map.put("SMS",new SMSHandler());
map.put("Email",new EmailHandler();
}
void processMessage(Message message) {
Handler handler = map.get(message.getNotificationType();
handler.handleMessage();
}
}
public abstract class Handler {
public abstract void handle(Mesage message) ;
}
public EmailHandler extends Handler {
public void handle(Message message) {
System.out.println("Sending email"): // similar class for phone.
}

注:这个设计在面试中被拒绝了。问题:

  1. 我们是否应该使消息抽象- EmailMessage、SMSMessage等?
  2. 注意到消息的内容因频道而异。就像。在电子邮件中,内容将很大。对于SMS,它要小得多。那么,消息应该是收敛性的吗?
  3. ,您如何能够支持一个新的eg..telegram消息,并且更改最少?

EN

回答 1

Stack Overflow用户

发布于 2022-07-22 13:37:39

当然,我并不是你的评审员,但他可能会说你打破了“坚实”原则的"O“,即开放-封闭原则,并指出:”软件实体(类、模块、功能等)应该开放供扩展,但关闭以进行修改“。

解决方案的问题是,如果需要支持新的通道,则需要向NotificationType Enum添加另一个实例。

让我们从接口开始:

代码语言:javascript
复制
public interface Message {
     //no need to define any methods here

}

public interface MessageHandler {
     void handleMessage(Message message);
     Class<?> getSupportedMessageType();
}

public interface MessageService {
     void processMessage(Message message);
}

已经有可能定义MessageServiceImpl类的最终版本,它无需在每次需要支持新通道时更改。

代码语言:javascript
复制
public class MessageServiceImpl implements MessageService
{

    private final Map<Class<?>, MessageHandler> handlers = new HashMap<>();

    public MessageServiceImpl(ICollection<MessageHandler> handlers) {
       foreach(MessageHandler handler : handlers)  {
           this.handlers.put(handler.getSupportedMessageType(), handler);
       }
    }

    public void processMessage(Message message)  {
        if (!this.handlers.containsKey(message.getType())) throw new InvalidArgumentException();

        this.handlers.get(message.getType()).handleMessage(message);

    }

在依赖注入框架的帮助下,也可能让DI处理新的消息处理程序实现。

然后,我们可以定义一个抽象类来抽象消息处理程序:

代码语言:javascript
复制
public abstract class AbsMessageHandler<T implements Message> implements MessageHandler {
    private final Class<T> supportedMessageType;
    protected AbsMessageHandler(Class<T> supportedMessageType) {
        this.supportedMessageType = supportedMessageType;
    }
    protected abstract void handleMessageInternal(T message);
    public Class<?> getSupportedMessageType() { return supportedMessageType; }

    public void handleMessage(Message message)
    {
        if (message == null) throw new InvalidArgumentException();
        if (message.getType() != getSupportedMessageType()) throw new InvalidArgumentException();
        handleMessageInternal((T) message);
    }
} 

唯一需要定义的是消息和消息处理程序实现:

代码语言:javascript
复制
public EmailMessage implements Message  {
    private string from; 
    private string to;
    private string cc;
    private string subject;
    private string messageBody;
    //getters and setters
}

public EmailMessageHandler extends AbsMessageHandler<EmailMessage> {
    public EmailMessage() {
       super(EmailMessage.class);
    }

    protected void handleMessageInternal(EmailMessage message) {
       // do what you like
    }
}

每次需要添加对新通道的支持时,只需添加两个新类,一个用于实现消息接口,另一个用于扩展AbsMessageHandler抽象类。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73078882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档