我正在尝试掌握我现在正在处理的项目的重构。基本上我有两个类,每个类都从一个接口扩展。
如果看一下我的代码,您会发现存在很多的代码重复,因为跨每个类的方法实现几乎完全相同-它们只是使用不同的对象类型(尽管InvestmentRequests
和FundingRequests
都实现相同的接口)。
那么重构此代码的理想方法是什么?可以从接口级别完成吗?我试图通过在接口中声明对象来做到这一点,例如:
RequestsData allRequests = null;
RequestsData fixedRequests = null;
RequestsData trackerRequests = null;
但是这看起来与我要执行的操作不一样,我不确定语法。
接口
public interface RequestDataBase<E,T> {
T getAllRequests();
T getFixedRequests();
T getTrackerRequests();
void add(E newRequest);
void addAll(List<E> accounts);
}
A级
public class FundingRequestData implements RequestDataBase<FundingRequest,FundingRequestData.FundingRequests> {
private static FundingRequests fundingRequests;
private static FundingRequests fixedFundingRequests;
private static FundingRequests trackerFundingRequests;
private static FundingRequestData instance = new FundingRequestData();
public static FundingRequestData getInstance() {
return instance;
}
private FundingRequestData() {
fundingRequests = new FundingRequests();
fixedFundingRequests = new FundingRequests();
trackerFundingRequests = new FundingRequests();
}
@Override
public FundingRequests getAllRequests() {
return fundingRequests;
}
@Override
public FundingRequests getFixedRequests() {
return fixedFundingRequests;
}
@Override
public FundingRequests getTrackerRequests() {
return trackerFundingRequests;
}
private void listSpecifier(FundingRequest request) {
if (request.getType().equals("FIXED")) {
fixedFundingRequests.add(request);
} else {
trackerFundingRequests.add(request);
}
}
@Override
public void add(FundingRequest newRequest) {
fundingRequests.add(newRequest);
listSpecifier(newRequest);
}
@Override
public void addAll(List<FundingRequest> accounts) {
fundingRequests.getRequests().addAll(accounts);
for (FundingRequest request : accounts) {
listSpecifier(request);
}
}
B级
public class InvestmentRequestData implements RequestDataBase<InvestmentRequest,InvestmentRequestData.InvestmentRequests> {
private static InvestmentRequests investmentRequests;
private static InvestmentRequests fixedInvestmentRequests;
private static InvestmentRequests trackerInvestmentRequests;
private static InvestmentRequestData instance = new InvestmentRequestData();
public static InvestmentRequestData getInstance() { return instance; }
private InvestmentRequestData() {
investmentRequests = new InvestmentRequests();
fixedInvestmentRequests = new InvestmentRequests();
trackerInvestmentRequests = new InvestmentRequests();
}
public void investAll() {
for (InvestmentRequest request : investmentRequests.getUnfulfilledRequests()) {
request.investAll();
}
}
public InvestmentRequests getAllRequests() {
return investmentRequests;
}
public InvestmentRequests getFixedRequests() { return fixedInvestmentRequests; }
public InvestmentRequests getTrackerRequests() {
return trackerInvestmentRequests;
}
private void listSpecifier(InvestmentRequest newRequest) {
if(newRequest.getType().equals("FIXED")) {
fixedInvestmentRequests.add(newRequest);
} else {
trackerInvestmentRequests.add(newRequest);
}
}
public void add(InvestmentRequest newRequest) {
investmentRequests.add(newRequest);
listSpecifier(newRequest);
}
public void addAll(List<InvestmentRequest> newRequests) {
for (InvestmentRequest request : newRequests) {
listSpecifier(request);
}
}
答案 0 :(得分:1)
您将无法在接口级别上折射通用对象,否则您会将FundingRequest和InvestmentRequest折射到同一个对象,我认为这不是您想要的。< / p>
我会折射A类和B类中的对象。但是,总体设计可能会得到改进。类似于让InvestmentRequest和FundingRequest实现一个Request接口,因此可以使用Request和Requests对象,而不是在RequestDataBase接口中使用泛型E和T。
答案 1 :(得分:1)
如果FundingRequest和InvestmentRequest都实现相同的接口(请求),那么您应该只处理请求。
如果您将类编码为仅与请求交互,那么我猜您会遇到某些情况,您必须区别对待这两种类型(否则您已经做完了!)
如果必须区别对待它们,我建议进行两步重构(在每一步之间运行单元测试!)
首先使用if(x FundingRequest的instance)选择一个代码路径或另一个。这使您可以进行最小的重构。这部分的目的是将您要讨论的两个类浓缩为一个类。
不过不要停在那里,在将其全部重构后,现在需要将这些instanceofs推送到两个请求类中。可能会在接口中添加一个新方法来调用实现,并将该if()语句的一条路径放入FundingRequest,将另一条路径放入InvestmentRequest。
在完成重构的这一部分后,您的课程应仅引用“请求”,而不是FundingRequest或InvestmentRequest。