繁体   English   中英

如果具有相同接口的类具有相似但不同的方法签名,该怎么办?

[英]What to do if classes with same interface having similar but different method signature?

如果具有相同接口的类具有相似但不同的方法签名,该怎么办?

假设我有一个计算不同成本的项目(最终得到总成本)。

在我的程序中,有几个计算器类,即ACostCalculatorBCostCalculator等。 当调用calculate()方法来计算成本时,成本容器也会传递给这些成本计算器。 在一个好的场景中,我可以为每个成本计算器制作CostCalculator接口。

但是,不同成本的计算需要不同的资源。 在我目前的计划中,它是这样的:

//getResource() are costly method while several costs need this. So do it outside calculate() method.
ResourceA resourceA = getResourceA(); 
ResourceB resourceB = getResourceB();

CostContainer costContainer = new CostContainer();
CostCalculator aCostCalculator = new ACostCalculator();
...
CostCalculator eCostCalculator = new ECostCalculator();

aCostCalculator.calculate(costContainer);
bCostCalculator.calculate(costContainer)
cCostCalculator.calculate(costContainer, resourceA);
dCostCalculator.calculate(costContainer, resourceA);
eCostCalculator.calculate(costContainer, resourceA, resourceB);

如果签名完全相同,我可以方便地做一个循环来立即执行。 但是,由于它们相似但不同,我甚至无法建立良好的界面。

我不确定是否有好方法可以这样做。 我能想到的是将所有calculate()方法推广到

calculate(CostContainer costContainer, List<Object> resources);

有任何想法吗? 谢谢回答。

如果资源在计算器的生命周期内保持不变:将资源传递给计算器的构造函数。

ResourceA resourceA = getResourceA(); 
ResourceB resourceB = getResourceB();

CostContainer costContainer = new CostContainer();

CostCalculator aCostCalculator = new ACostCalculator();
CostCalculator bCostCalculator = new BCostCalculator();
CostCalculator cCostCalculator = new CCostCalculator(resourceA);
CostCalculator dCostCalculator = new DCostCalculator(resourceA);
CostCalculator eCostCalculator = new ECostCalculator(resourceA, resourceB);

aCostCalculator.calculate(costContainer);
bCostCalculator.calculate(costContainer);
cCostCalculator.calculate(costContainer);
dCostCalculator.calculate(costContainer);
eCostCalculator.calculate(costContainer);

针对公共接口改变签名的问题听起来很像适配器设计模式(对象适配器变体)解决的问题:

适配器模式(GoF)

根据您的情况,您只能使用适配器来处理不合格的计算器。 实际上只有两种类型的适配器,Type1用于签名(costContainer, resourceA) ,Type2用于签名(costContainer, resourceA, resourceB) 使用你的例子:

适用于您的示例的适配器模式

适配器的优点是它是一种已知的设计模式(由GoF在1995年发布),它允许具有不同签名的最终calculate(...)方法。 如果发生上下文变化(例如资源变化),可以动态更新适配器。

缺点显然是额外的类,间接等等。它比选择的答案更复杂,但更灵活,特别是如果你不能修改适配器的API。

您可以使用可变参数

public interface CostCalculatorInterface {
    public void calculate(CostContainer container, Object... resources);
}

(或用另一个超类ResourceAResourceB替换Object )。

在实现接口的类中, resources将是Object[]因此您可以将它们称为resources[0]resources[1]等。

这是你在Generics中实际使用的东西:

    Resource resourceA = new ResourceA();
    Resource resourceB = new ResourceB();
    CostContainer costContainer = new CostContainer();
    CostCalculator<Resource> costCalculatorA = new ACostCalculator();
    costCalculatorA.calculate(costContainer,resourceA,resourceB);
    CostCalculator<Resource> costCalculatorB = new BCostCalculator();
    costCalculatorB.calculate(costContainer,resourceA);


interface Resource {
    //Your code
}

class ResourceA implements Resource {
    //Your code
}

class ResourceB implements Resource {
    //Your code
}

class CostContainer {
    //Your code
}

interface CostCalculator<T extends Resource> {
    void calculate(CostContainer costContainer, T... resources);
}

class ACostCalculator implements CostCalculator<Resource>{

    @Override
    public void calculate(CostContainer costContainer, Resource... resources) {
        System.out.println("Test");
    }
}

class BCostCalculator implements CostCalculator<Resource>{

    @Override
    public void calculate(CostContainer costContainer, Resource... resources) {
        System.out.println("Test2");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM