多渠道通知系统LLD设计优化及扩展问题问询
多渠道通知系统设计问题解答
需求背景
需设计支持Email、SMS、WhatsApp等多渠道的通知系统类,要求具备易扩展性。
原设计代码
class Message { NotificationType type; // email, sms msgId; String content; } class 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(Message message); } public class EmailHandler extends Handler { public void handle(Message message) { System.out.println("Sending email"); // similar class for phone. } }
注:该设计在面试中未通过。
技术问题
- 是否应当将Message设计为抽象类,派生出EmailMessage、SMSMessage等子类?
- 考虑到不同渠道的消息内容存在差异(例如邮件内容较长,SMS内容较短),是否应当将Message设为抽象类?
- 如何以最小改动实现对新增渠道(如Telegram消息)的支持?
问题解答
1. 是否应当将Message设计为抽象类,派生出EmailMessage、SMSMessage等子类?
不是必须,但如果不同渠道的消息有独特属性差异(比如邮件有主题、抄送列表,SMS有运营商签名),这种设计会更合理。它能让类型边界更清晰,避免在通用Message里堆砌冗余字段,同时编译器可以帮你做类型校验,防止把邮件专属属性错误传入SMS处理逻辑。但如果所有渠道的消息核心只有内容、接收方这类通用字段,保持单一Message类也完全可行,核心看业务复杂度。
2. 考虑到不同渠道的消息内容存在差异(例如邮件内容较长,SMS内容较短),是否应当将Message设为抽象类?
内容长度差异属于业务规则约束,不是结构差异,单靠抽象类解决不了问题。更合适的处理方式是:
- 如果要在消息层面做约束,可以给Message添加校验逻辑,或者在抽象Message中定义抽象方法
validateContent(),让子类实现各自的长度、格式校验规则。 - 也可以把校验逻辑放到对应的Handler中,在处理消息前先检查内容是否符合渠道要求。
所以要不要把Message设为抽象类,核心看有没有结构上的字段差异,而非内容长度这类规则差异。
3. 如何以最小改动实现对新增渠道(如Telegram消息)的支持?
基于你现有代码的结构,最小改动的步骤如下:
- 新增
TelegramHandler类,继承抽象Handler,实现handle(Message message)方法,编写Telegram消息的发送逻辑。 - 在
MessagingServiceImpl的静态代码块中,添加map.put("Telegram", new TelegramHandler())。 - 如果Telegram没有特殊消息属性,直接用现有Message类即可;如果有专属属性,要么在现有Message中添加可选字段(不推荐,会导致类越来越臃肿),要么派生
TelegramMessage子类,但这需要修改Handler的方法参数,会波及现有代码,不算最小改动。
另外,现有代码存在几个语法和逻辑问题,需要先修正才能顺利扩展:
MessagingServiceImpl中的map需要定义为静态成员变量并初始化,比如private static Map<NotificationType, Handler> handlerMap = new HashMap<>();processMessage方法中调用的handler.handleMessage()要改为handler.handle(message),否则处理逻辑拿不到消息内容EmailHandler的类定义缺少class关键字,属于语法错误
内容的提问来源于stack exchange,提问作者Praveen Nvs
相关产品推荐
相关产品推荐

