实现应作为可选的 类
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中,Optional
是final
class,不是接口。为了正确解决此类问题,我将编写自己的 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所说,这是一个奇怪的想法。假设您想计算两个 int
的 xy。有时它是未定义的,那么你会实现一个 Maybe<Integer>
吗?然后是另一个实现,例如nCr(x, y)?
这听起来不对吧?问题是你将事物的起源(交叉点、力量、选择)绑定到事物本身。但是两个 Shape
的交集只不过是 Shape
再次(或者什么都不是,可以通过 Optional
很好地表示)。 或者甚至更好 null
; 就叫我老派吧).
OO 方法在这里毫无意义,因为没有新的对象种类。 22 与 nCr(4, 1) 完全相同,并且都与 4.
完全相同
另一件事是您必须调用 ShapesIntersection
构造函数。这实际上是一个 static 调用,因此您不妨编写一个静态辅助方法。
将 Shape
扩展一些 IntersectableShape
可能有意义。在某些情况下,某些操作对于此类事情来说足够普遍,请参见例如FluentIterable,但我怀疑你会做那么多交叉路口。
想象一下,找出两个形状是否相交。两个形状的交集可能是另一种形状,也可能什么都不是。如果 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中,Optional
是final
class,不是接口。为了正确解决此类问题,我将编写自己的 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所说,这是一个奇怪的想法。假设您想计算两个 int
的 xy。有时它是未定义的,那么你会实现一个 Maybe<Integer>
吗?然后是另一个实现,例如nCr(x, y)?
这听起来不对吧?问题是你将事物的起源(交叉点、力量、选择)绑定到事物本身。但是两个 Shape
的交集只不过是 Shape
再次(或者什么都不是,可以通过 Optional
很好地表示)。 或者甚至更好 null
; 就叫我老派吧).
OO 方法在这里毫无意义,因为没有新的对象种类。 22 与 nCr(4, 1) 完全相同,并且都与 4.
完全相同另一件事是您必须调用 ShapesIntersection
构造函数。这实际上是一个 static 调用,因此您不妨编写一个静态辅助方法。
将 Shape
扩展一些 IntersectableShape
可能有意义。在某些情况下,某些操作对于此类事情来说足够普遍,请参见例如FluentIterable,但我怀疑你会做那么多交叉路口。