在Java中,我如何根据参数返回两种不同类型的值?

huangapple go评论75阅读模式
英文:

In Java, how can I return two different types based on an argument?

问题

假设我有一个像这样的方法:

public AbstractContractApplication acceptOffer(AcceptedOfferDto dto)
{
    // 各种应用程序逻辑
    Contract contract; // 与上述代码深度集成
    return processedApplication;  // 也与上述代码深度集成
}

我想重构我的方法,根据AcceptedOfferDto中提供的参数,有时返回contract而不是processedApplication。理想情况下是这样的:

if (AcceptedOfferDto.getReturnConfig() == 1){
    return contract;
}
else {
    return processedApplication; 
}

有没有一种干净的方法来做到这一点,而不涉及复制和粘贴函数中大部分代码,或者重构大块极其重要的业务逻辑?

目前的思路是创建一个包含两个对象实例的类,然后从中选择正确的值。还有哪些其他选项可用?

英文:

Say that I have a method like this:

public AbstractContractApplication acceptOffer(AcceptedOfferDto dto)
{
    // various application stuff
    Contract contract; // deeply integrated into the above code
    return processedApplication;  // also deeply integrated into the above code 
}

I would like to refactor my method to sometimes return contract instead of processedApplication based on an argument provided in the AcceptedOfferDto. Ideally something like this:

if (AcceptedOfferDto.getReturnConfig() == 1){
return contract;
}

else {
return processedApplication; 
}

Is there a clean way to do this which does not involve copy and pasting the bulk of the code in the function or refactoring a large block of extremely important business logic?

The current line of thinking is to create a class that contains instances of both objects and just select the correct value from that. What other options might be available?

答案1

得分: 3

假设 ContractAbstractContractApplication 没有共同的有用特性可以依赖多态性,而且您无法进行太多的重构,您可以使用以下方法:

public interface EitherOne<A, B> {
    public default boolean isA() { return false; }
    public default boolean isB() { return false; }
    public default A getA() { throw new IllegalStateException(); }
    public default B getB() { throw new IllegalStateException(); }

    public static <A, B> EitherOne<A, B> a(A a) {
        return new EitherOne<>() {
            @Override public boolean isA() { return true; }
            @Override public A getA() { return a; }
        };
    }

    public static <A, B> EitherOne<A, B> b(B b) {
        return new EitherOne<>() {
            @Override public boolean isB() { return true; }
            @Override public B getB() { return b; }
        };
    }
}

我真的不建议任何人使用这种方法。它应该只用作复杂情况下的一个快速且不太正规的应急解决方案。

接下来,您可以尝试这样做:

public EitherOne<Contract, AbstractContractApplication> acceptOffer(AcceptedOfferDto dto) {
    // 各种应用程序逻辑
    AbstractContractApplication processedApplication = ...;
    Contract contract = ...; // 与上述代码深度集成
    if (AcceptedOfferDto.getReturnConfig() == 1) return EitherOne.a(contract);
    return EitherOne.b(processedApplication);  // 也与上述代码深度集成
}
英文:

Supposing that Contract and AbstractContractApplication have nothing useful in common to rely on polimorphism and you can't refactor too much things, you could use this:

public interface EitherOne&lt;A, B&gt; {
    public default boolean isA() { return false; }
    public default boolean isB() { return false; }
    public default A getA() { throw new IllegalStateException(); }
    public default B getB() { throw new IllegalStateException(); }

    public static &lt;A, B&gt; EitherOne&lt;A, B&gt; a(A a) {
        return new EitherOne&lt;&gt;() {
            @Override public boolean isA() { return true; }
            @Override public boolean getA() { return a; }
        };
    }

    public static &lt;A, B&gt; EitherOne&lt;A, B&gt; b(B b) {
        return new EitherOne&lt;&gt;() {
            @Override public boolean isB() { return true; }
            @Override public boolean getB() { return b; }
        };
    }
}

I really don't recommend anyone using this. It should be used only as a quick and dirty escape hatch hack for complicated situations.

Then, you can try this:

public EitherOne&lt;Contract, AbstractContractApplication&gt; acceptOffer(AcceptedOfferDto dto) {
    // various application stuff
    AbstractContractApplication processedApplication = ...;
    Contract contract = ...; // deeply integrated into the above code
    if (AcceptedOfferDto.getReturnConfig() == 1) return EitherOne.a(contract);
    return EitherOne.b(processedApplication);  // also deeply integrated into the above code 
}

答案2

得分: -1

使用多态性。
contract(合同)和processedApplication(处理后的申请)的类型必须是AbstractContractApplication(抽象合同申请)的子类型。

英文:

Use Polymorphism.
The type of contract (Contract) and processedApplication (?) must be subtypes of AbstractContractApplication.

huangapple
  • 本文由 发表于 2020年3月4日 06:18:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/60516351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定