想象一下,找出两个形状是否相交.两个形状的交集可以是另一种形状,也可以不是.如果没有intersects(Shape)
方法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
}
}
Run Code Online (Sandbox Code Playgroud)
在JDK中,Optional
是一个final
类,而不是一个接口.为了正确解决像这样的问题,我将编写自己的Maybe
界面,如下所示:
public inteface Maybe<T> {
T get();
boolean isPresent();
default Optional<T> asOptional() {
return isPresent() ?
Optional.of(get()) :
Optional.empty();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在需要可选行为时坚持使用Maybe解决方案,可能会有什么警告?此外,这项任务似乎非常普遍.我是否通过引入自己的Maybe
界面重新发明轮子?
我应该补充说,使用单独的类和接口的整个麻烦是省略使用静态方法实现行为.
你在这里重新发明轮子.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);
}
Run Code Online (Sandbox Code Playgroud)
请注意,Optional.empty()
并且Optional.of(....)
是工厂方法,用于创建Optional的适当实例.Java 8流,函数和其他支持结构使用许多静态工厂方法来创建这些最终类的实例.
正如rolfl所说,这是一个奇怪的想法.想象一下,你想要计算两年的x yint
.有时候它是未定义的,你会实现Maybe<Integer>
吗?然后是另一个例如nCr(x,y)的实现?
这听起来不对,不是吗?问题在于你将事物的起源(交集,权力,选择)绑定到事物本身.但两个人Shape
的交集只不过是一个Shape
(或者根本没有,可以很好地表现出来Optional
.或者甚至更好地表达;只要叫我老派).null
OO aproach在这里毫无意义,因为没有新的对象.2 2与nCr(4,1)完全相同,两者都与4完全相同.
另一件事是你必须调用ShapesIntersection
构造函数.这实际上是一个静态调用,所以你也可以编写一个静态助手方法.
Shape
某些人延伸IntersectableShape
可能有意义.有些情况下某些操作对于这样的事情是足够普遍的,例如FluentIterable,但我怀疑你会做出那么多的交叉点.