实现应作为可选的 类

Implementing classes that should behave as Optional

想象一下,找出两个形状是否相交。两个形状的交集可能是另一种形状,也可能什么都不是。如果 Shape 中没有 intersects(Shape) 方法,那么我认为正确的面向对象解决方案是:

public final class ShapesIntersection implements Maybe<Shape> {
    public ShapesIntersection(Shape a, Shape b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public boolean isPresent() {
        // find out if shapes intersect
    }

    @Override
    public Shape get() {
        // find the common piece of two shapes
    }
}

在JDK中,Optionalfinalclass,不是接口。为了正确解决此类问题,我将编写自己的 Maybe 界面,如下所示:

public inteface Maybe<T> {
    T get();
    boolean isPresent();
    default Optional<T> asOptional() {
       return isPresent() ?
           Optional.of(get()) :
           Optional.empty();
    }
}

如果我在需要可选行为时坚持使用这个实施 Maybe 的解决方案,可能会有什么注意事项?而且,这个任务似乎很普遍。我是在重新发明轮子,引入我自己的 Maybe 界面吗?

我应该补充一点,使用单独的 class 和接口的整个麻烦在于忽略使用静态方法实现行为。

你在这里重新发明轮子。 Optional 是 final 的原因是因为真的没有理由改变它,并且内部语义需要在整个用法中保持一致。

这里真正的问题是构造函数的逻辑。您不应该使用构造函数来确定交集的逻辑。你想要的是一个(静态的?)为你执行计算的方法,以及 returns 相关的 Optional.

public static Optional<Shape> intersection(Shape a, Shape b) {
    // compute if there is an overlap
    if (!checkOverlaps(a,b)) {
        return Optional.empty();
    }
    Shape intersection  = ....
    return Optional.of(intersection);
}

请注意,Optional.empty() and Optional.of(....) 是创建 Optional 的适当实例的工厂方法。 Java 8 个流、函数和其他支持结构使用大量静态工厂方法来创建这些最终的实例 类。

正如rolfl所说,这是一个奇怪的想法。假设您想计算两个 intxy。有时它是未定义的,那么你会实现一个 Maybe<Integer> 吗?然后是另一个实现,例如nCr(x, y)?

这听起来不对吧?问题是你将事物的起源(交叉点、力量、选择)绑定到事物本身。但是两个 Shape 的交集只不过是 Shape 再次(或者什么都不是,可以通过 Optional 很好地表示)。 或者甚至更好 null; 就叫我老派吧).

OO 方法在这里毫无意义,因为没有新的对象种类。 22 与 nCr(4, 1) 完全相同,并且都与 4.

完全相同

另一件事是您必须调用 ShapesIntersection 构造函数。这实际上是一个 static 调用,因此您不妨编写一个静态辅助方法。

Shape 扩展一些 IntersectableShape 可能有意义。在某些情况下,某些操作对于此类事情来说足够普遍,请参见例如FluentIterable,但我怀疑你会做那么多交叉路口。