如何使用非常相似的方法但使用不同的类型来重构两个类

时间:2018-11-09 16:07:45

标签: java oop types interface refactoring

我正在尝试掌握我现在正在处理的项目的重构。基本上我有两个类,每个类都从一个接口扩展。

如果看一下我的代码,您会发现存在很多的代码重复,因为跨每个类的方法实现几乎完全相同-它们只是使用不同的对象类型(尽管InvestmentRequestsFundingRequests都实现相同的接口)。

那么重构此代码的理想方法是什么?可以从接口级别完成吗?我试图通过在接口中声明对象来做到这一点,例如:

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);
        }
    }

2 个答案:

答案 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。