您必须设计类来构建一个支持多种渠道的通知系统,如电子邮件、SMS、Whatsapp。它应该容易扩展。
My设计:
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.
}注:这个设计在面试中被拒绝了。问题:
。
发布于 2022-07-22 13:37:39
当然,我并不是你的评审员,但他可能会说你打破了“坚实”原则的"O“,即开放-封闭原则,并指出:”软件实体(类、模块、功能等)应该开放供扩展,但关闭以进行修改“。
解决方案的问题是,如果需要支持新的通道,则需要向NotificationType Enum添加另一个实例。
让我们从接口开始:
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类的最终版本,它无需在每次需要支持新通道时更改。
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处理新的消息处理程序实现。
然后,我们可以定义一个抽象类来抽象消息处理程序:
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);
}
} 唯一需要定义的是消息和消息处理程序实现:
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抽象类。
https://stackoverflow.com/questions/73078882
复制相似问题