更新:又增加了一个问题(问题 #4)。
大家好
我正在为自己构建一个自定义电子邮件实用程序。现在,为了遵守单一职责原则,我想要以下类:MailerSender、MailProvider 和 EmailObject。 MailSender 更像是一个委托(delegate),请在下面查看:
public class MailSender {
private IMailProvider mailProvider;
public void setMailProvider (IMailProvider provider) {
this.mailProvider = provider;
}
// option to set it up during construction
public MailSender (IMailProvider provider) {
this.mailProvider = provider;
}
public void sendEmail(EmailObject obj) {
if(mailProvider == null)
throw new RuntimeException("Need a mail provider to send email.");
try {
mailProvider.send(obj);
} catch (Exception e) {
// do something here
}
}
}
MailSender 需要一个 IMailProvider 电子邮件提供商来完成发送电子邮件的工作。在下面找到它:
public interface IMailProvider {
public void sendEmail(EmailObject obj);
}
public class SMTPEmailProvider implements IMailProvider {
public void sendEmail(EmailObject obj) {
// use SMTP to send email using passed-in config
}
}
public class JMSEmailProvider implements IMailProvider {
public void sendEmail(EmailObject obj) {
// push emails to JMS queue to be picked up by another thread
}
}
我在上面定义了几个策略,但它可以扩展到任何数字。由于 MailSender 可以随时更改其提供者,因此它有效地实现了策略模式,对吗?
EmailObject 是一个包含相关电子邮件信息的 POJO:
public class EmailObject {
private String to;
private String from;
private String cc;
private String subject;
private String body;
// setters and getters for all
}
客户端代码将如下所示:
MailSender sender = new MailSender(new SMTPMailProvider());
sender.send(new EmailObject());
sender.setMailProvider(new JMSMailProvider());
sender.send(new EmailObject());
我的问题是:
1. 我实现了策略模式了吗?
2、这个设计好不好? MailProvider 知道 EmailObject 有意义吗?
3. 如果我稍后有一个需要附件的新 EmailObject 怎么办?
4. 客户端代码现在需要在创建 MailSender 之前获取特定的 MailProvider ...这有意义吗?
最佳答案
好的,我们来解决您的问题。
1) 模糊地,是的。你可以争辩说你有“算法”或“策略”,你可以在它们之间进行选择。但是,我更愿意将策略模式视为与算法相关的东西。例如,获取搜索结果的不同方式。在这里,您要处理不同的代理,您将发送电子邮件的角色委托(delegate)给这些代理。这是一种常见的设计,但我不确定是否一定要将其称为策略。无论哪种方式,设计模式都是为了帮助您思考,而不是将您锁定在特定的名称上。
2)我认为设计合理。我会使用接口(interface)而不是实际的类,尤其是对于 EMailObject。此外,应该有一个电子邮件对象的工厂,不要只是新建它们。每个提供商也很可能会提供自己的包含包裹详细信息的“电子邮件对象”。您发送的是内容,而不是“信封”。
3) 这是使用接口(interface)而不是类的另一个很好的理由。您可能希望包含元数据和潜在附件的 getter/setter,因为它们是您域(电子邮件)的合法部分。
关于java - 在 Java 中使用策略模式的电子邮件程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/875703/