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

Java 如何使用非常相似的方法但使用不同的类型重构两个类,java,oop,types,interface,refactoring,Java,Oop,Types,Interface,Refactoring,我正在努力掌握一个我正在进行的项目的重构。基本上我有两个类,每个类都从一个接口扩展而来 如果你看一下我的代码,你会发现有很多代码重复,因为每个类的方法实现几乎完全相同——它们只是使用不同的对象类型(尽管InvestmentRequests和FundingRequests也实现了相同的接口) 那么,重构这段代码的理想方法是什么呢?可以从接口级别完成吗?我试图通过在我的界面中声明对象来实现这一点,如下所示: RequestsData allRequests = null; RequestsData

我正在努力掌握一个我正在进行的项目的重构。基本上我有两个类,每个类都从一个接口扩展而来

如果你看一下我的代码,你会发现有很多代码重复,因为每个类的方法实现几乎完全相同——它们只是使用不同的对象类型(尽管
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);
}
公共接口数据库{
T getAllRequests();
T getFixedRequests();
T getTrackerRequests();
无效添加(新请求);
void addAll(列出账户);
}
甲级

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);
    }
}
公共类FundingRequestData实现RequestDataBase{
私人静态资金请求资金请求;
私人静态资金申请固定资金申请;
私人静态资金请求跟踪资金请求;
私有静态FundingRequestData实例=新建FundingRequestData();
公共静态FundingRequestData getInstance(){
返回实例;
}
私人基金请求数据(){
fundingRequests=新的fundingRequests();
fixedFundingRequests=新的FundingRequests();
trackerFundingRequests=新的FundingRequests();
}
@凌驾
公共资金请求getAllRequests(){
归还资金申请;
}
@凌驾
公共资金请求getFixedRequests(){
返回固定资金请求;
}
@凌驾
公共资金请求getTrackerRequests(){
返回TrackerFindingRequests;
}
专用作废列表说明符(资金申请){
if(request.getType().equals(“FIXED”)){
fixedFundingRequests.add(请求);
}否则{
TrackerFindingRequests.add(请求);
}
}
@凌驾
公共作废添加(资金申请新申请){
fundingRequests.add(newRequest);
列表说明符(newRequest);
}
@凌驾
公共无效添加所有(列出帐户){
fundingRequests.getRequests().addAll(账户);
用于(资金申请:账户){
列表说明符(请求);
}
}
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);
        }
    }
公共类InvestmentRequestData实现RequestDataBase{
私人静态投资请求InvestmentRequests;
私人静态投资请求fixedInvestmentRequests;
私人静态投资请求跟踪投资请求;
私有静态InvestmentRequestData实例=新建InvestmentRequestData();
public static InvestmentRequestData getInstance(){return instance;}
私人投资请求数据(){
investmentRequests=新的investmentRequests();
fixedInvestmentRequests=新投资请求();
trackerInvestmentRequests=新投资请求();
}
公营机构{
for(InvestmentRequest请求:investmentRequests.GetUnfulledRequests()){
request.investAll();
}
}
公共投资请求getAllRequests(){
返还投资请求;
}
public InvestmentRequests getFixedRequests(){返回fixedInvestmentRequests;}
公共投资请求getTrackerRequests(){
返回trackerInvestmentRequests;
}
私有无效列表说明符(InvestmentRequest newRequest){
if(newRequest.getType().equals(“FIXED”)){
fixedInvestmentRequests.add(新请求);
}否则{
trackerInvestmentRequests.add(newRequest);
}
}
公共作废添加(投资请求新请求){
investmentRequests.add(newRequest);
列表说明符(newRequest);
}
公共void addAll(列出新请求){
对于(投资请求:新请求){
列表说明符(请求);
}
}

您将无法在接口级别折射通用对象,否则您将同时折射FundingRequest和InvestmentRequest到同一对象,我认为这不是您的意图


我会折射A类和B类中的对象。但是,总体设计可能会有所改进。比如让InvestmentRequest和FundingRequest实现一个请求接口,这样就不用在RequestDataBase接口中使用泛型E和T,而可以使用Request和Requests对象。

如果FundingRequest和InvestmentRequest都实现相同的接口(请求),那么您应该只处理请求

如果您将类编码为仅与请求交互,我猜您会遇到一些情况,您必须以不同的方式对待这两种类型(否则您已经完成了!)

如果您必须以不同的方式对待它们,我建议采用两步重构(在每一步之间运行单元测试!)

首先使用if(x instanceof FundingRequest)来选择一个或另一个代码路径。这可以让您进行最低限度的重构。本部分的目标是将您正在讨论的两个类压缩为一个类

不过,不要就此止步,在您将其全部重构之后,现在需要将这些InstanceOf推入两个请求类中。可能需要向调用实现的接口添加一个新方法,并将if()语句的一条路径放入FundingRequest,另一条路径放入InvestmentRequest


当您完成重构的这一部分时,您的类应该只引用“请求”,从不资助Request或InvestmentRequest。

抽象超类如何?@Glains我认为当我使用的类型不同时,这不起作用?不需要将除
实例
之外的变量声明为静态。此外,您还可以像处理
请求数据库
@tsolakp一样对抽象类进行参数化哟