在报告模块中,有一个我想要重构的电子邮件服务,因此我可以将其用作通用电子邮件服务 . 实际上,我需要在用户重置密码时向用户发送电子邮件,这是重构的主要原因 .
public class EmailService{
public Email buildEmail(ReportRequest reportRequest){
//build email using ReportRequest object here
}
}
@Builder
@Getter
@Setter
@AllArgsConstructor
public class Email implements Serializable {
private String subject;
private String text;
private String recipientEmail;
private String senderEmail;
}
我重构的方式是这样的:
我创建了一个名为EmailService的接口,它有一个buildEmail()方法 . 我在想,实现这一目标的任何一个类都有不同的构建/构建其电子邮件的方式 .
public interface EmailService{
public Email buildEmail();
}
public class ReportEmailService implements EmailService{
public Email buildEmail(){}
}
public class PasswordEmailService implements EmailService{
public Email buildEmail(){}
}
我现在的问题是,由于构建电子邮件将使用不同的对象(例如ReportRequest或其他对象,如AccountInfo),将所需对象传递到buildEmail()的最佳方法是什么?
我在这里做的是创建另一个方法并为buildEmail()中使用的所需对象创建一个类变量 .
基本上,现在它看起来像这样:
public class ReportEmailService implements EmailService{
private ReportRequest reportRequest;
public void sendEmail(ReportRequest reportRequest){
this.reportRequest = reportRequest;
Email email = buildEmail();
}
public Email buildEmail(){
#build email now using the report request object.
}
}
public class PasswordResetEmailService implements EmailService{
private AccountInfo accountInfo;
public void sendEmail(AccountInfo accountInfo){
this.accountInfo= accountInfo;
Email email = buildEmail();
}
public Email buildEmail(){
#build email now using the account info object.
}
}
我觉得我的做法有点尴尬 . 我可能在设计模式和重构方面错过了一些基本的东西,那么重构这个可能是最好的方法呢?或者buildEmail()如何能够访问构建电子邮件时所需的特定对象 .
2 回答
泛型可以帮助您解决这个问题 .
像这样声明接口:
和你的实现这样:
"Generics"部分是V形符号之间的部分(
<T>
),它充当您稍后为每个实现定义的类型的占位符 .有关域驱动设计的书籍定义服务是单例,因此在大多数情况下,您不应创建同一服务的多个实例 .
您可以实现多个电子邮件服务,也可以委托参数 .
然后,您的
ReportRequest
和AccountInfo
类可以实现EmailFactory
,甚至更好,您创建一个适配器类,它知道如何为每种类型buildEmail
...通过这种方式,您可以实现单个
EmailService
,它只知道如何发送电子邮件 . 并且您为要作为电子邮件发送的每种类型的事物实现特定的包装器/适配器 .这也很容易扩展,允许不同类型的电子邮件用于不同的域类,如
FullDetailsAccountInfoEmailFactory
和SummaryAccountInfoEmailFactory
.如果您开始使用标准类型,也许可以获得奖励积分
然后你可以做的事情