![](/img/trans.png)
[英]IntelliJ or Eclipse refactoring all usages of a method to a method on a different class/interface
[英]Refactoring a class method to an interface in java
在報告模塊中,有一個我想重構的電子郵件服務,因此我可以將其用作通用電子郵件服務。 實際上,當用戶想要重設密碼時,我有向他們發送電子郵件的要求,這是重構的主要原因。
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()如何在構建電子郵件時訪問所需的特定對象。
泛型可以幫助您解決此問題。
像這樣聲明接口:
interface EmailService<T> {
Email buildEmail(T t);
}
和您的實現方式如下:
class ReportEmailService<ReportRequest> implements EmailService {
Email buildEmail(ReportRequest req) {
...
}
}
“泛型”部分是人字形( <T>
)之間的部分,它充當您稍后為每個實現定義的類型的占位符。
有關域驅動設計的書籍將服務定義為單例,因此在大多數情況下,您不應創建同一服務的多個實例。
您可以實現多個電子郵件服務,也可以委托給該參數。
interface EmailService {
boolean send(EmailFactory arg)
interface EmailFactory {
Email buildEmail();
}
}
然后,您的ReportRequest
和AccountInfo
類可以實現EmailFactory
,或者甚至更好,您可以創建一個適配器類,該類知道如何為每種類型buildEmail
...
class ReportRequestEmailFactory implements EmailFactory {
private ReportRequest report;
public Email buildEmail() {
return ...
}
}
class AccountInfoEmailFactory implements EmailFactory {
private AccountInfo account;
public Email buildEmail() {
return ...
}
}
這樣,您可以實現一個只知道如何發送電子郵件的單個EmailService
。 然后,為要作為電子郵件發送的每種類型的事物實現特定的包裝器/適配器。
這也可以輕松擴展,以允許為不同的域類使用不同類型的電子郵件,例如FullDetailsAccountInfoEmailFactory
和SummaryAccountInfoEmailFactory
。
如果您開始使用標准類型,可能會獲得加分
class EmailService implements Consumer<Email> {
public void accept(Email email) {
// TODO: send email
}
}
class AccountInfoEmailTransformer implements Function<AccountInfo,Email> {
public Email apply(AccountInfo t) {
// TODO: transform AccountInfo to Email
return ...
}
}
然后你可以做類似的事情
EmailService emailer = ...
AccountInfoEmailFunction transformer = ...
List<AccountInfo> accounts = ...
accounts.stream().map(transformer).forEach(emailer);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.