Implementing classes that should behave as optional

Imagine if two forms intersect. The intersection of two forms can be either another form or nothing. If Shape does not have an intersects(Shape) method, then I think the following would be the right object-oriented solution:

 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 } } 

In JDK, Optional is the final class, not the interface. In order to correctly solve problems such as this, I'm going to write my own Maybe interface, which will look like this:

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

What can be the caveats if I stick to this solution that implements, perhaps when I need extra behavior? In addition, this task seems to be very universal. I reinvent the wheel here by introducing my own interface. Maybe ?

I must add that the whole problem with a separate class and interface is to omit the implementation of the behavior using static methods.

+8
java oop optional
source share
2 answers

As rolfl said, this is a strange idea. Imagine you want to compute x y for two int s. Sometimes it is undefined and you would use Maybe<Integer> ? And then another implementation, for example. nCr (x, y)?

Sounds wrong, doesn't it? The problem is that you connect the origin of the thing (intersection, power, choice) with the thing itself. But the intersection of two Shape again no more than a Shape (or nothing at all that can be well represented through Optional . Or even better with null , just call me at the old school).

The OO approximation does not make sense here, since there is no new type of object. 2 2 is the same as nCr (4, 1), and both are exactly the same as 4.

Another thing is that you must call the ShapesIntersection constructor. This is actually a static call, so you can write a static helper method instead.

Extending Shape some IntersectableShape may make sense. There are times when some operations are common enough for such a thing, see, for example, FluentIterable , but I doubt that you will make so many intersections.

+5
source share

You reinvent the wheel here. The reason Optional is final because there is no reason to change it, and internal semantics require consistency in use.

The real problem here is the logic of your constructor. You should not use the constructor to define the intersection logic. What you want is a method (static?) That does the calculation for you and returns the corresponding optional parameter.

 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); } 

Note that Optional.empty() and Optional.of(....) are factory methods that create the corresponding instances of the Optional. Threads, functions, and other supporting Java 8 structures use a number of static factory methods to instantiate these other final classes.

+8
source share

All Articles