如何实现参数化运算

How to implement parameterized arithmetic

我正在设计一个库,该库提供大量 classes 来执行繁重的数字运算。我不想将库的用户限制为单一数字类型,例如 intdoubleBigDecimal - 因此如果我可以使用泛型允许用户选择自己的号码类型。我可以接受使用原始包装器 classes 而不是原始本身所带来的开销,这是使用泛型所必需的,但我的问题在于执行算术。

如果我创建一个假设的 class MathematicalObject<N extends Number>,那么用户可以使用任何类型来存储扩展数字的数字 - IntegerDoubleBigDecimal,等等。但是 Number class 不提供任何算术接口 - 我不能添加两个 Number 而不将它们转换为 double 或类似的东西 - 这可能会危及数字的准确性(例如,如果使用 BigDecimal)。

那么,实现允许我执行算术的数字参数化使用的最高效方法是什么?

您可以使用工厂来创建 MathematicalObject。 MathematicalObject 的构造函数可以接受一种策略 class 专门为该参数化类型执行数学运算,而工厂只是根据参数化类型选择正确的策略。

public class MathemeaticalObject<N extends Number> {
    private final NumberOperations<N> ops;
    public MatchematicalObject(NumberOperations<N> ops) {
        this.ops = ops;
    }

    public N myComplexOperation(N other) {
        return ops.add(this, other);
    }
}

public class MathematicalObjectFactory {
    MathematicalObject<Integer> integerObject() {
        return new MathematicalObject(new IntegerOperations());
    }
    ....
}

public interface NumberOperations<N extends Number> {
    N add(N other);
}

public class IntegerOperations implements NumberOperations<Integer> {
    @Override
    public Integer add(Integer first, Integer second) {
        return first + second;
    }
}

缺点是您受限于支持的 N 值。但我认为可能没有办法解决这个问题。鉴于无法直接使用原始数学运算,它还可能会产生一些混乱的代码。

您可以为算术运算定义自己的接口。 要使用 BigInteger 或类似的 classes,您只需将 class subclass 并使 subclass 实现您的接口即可。 对于原始类型,您必须编写自己的 Wrapper class :(

这是设计模式适配器:https://en.wikipedia.org/wiki/Adapter_pattern