Java 9 with JShell
上QQ阅读APP看书,第一时间看更新

Using feedback from domain experts

Now, it is time to have a meeting with our domain expert, that is, someone that has an excellent knowledge of 2D geometry. We can use the UML diagram to explain the object-oriented design for the solution. After we explain the different classes that we will use for abstracting the behavior, the domain expert explains to us that there are many shapes that have something in common and that we can generalize the behavior even further. The following six shapes are regular polygons:

  • An equilateral triangle (the EquilateralTriangle class) has three sides
  • A square (the Square class) has four sides
  • A regular pentagon (the RegularPentagon class) has five sides
  • A regular hexagon (the RegularHexagon class) has six sides
  • A regular octagon (the RegularOctagon class) has eight sides
  • A regular decagon (the RegularDecagon class) has ten sides

Regular polygons are polygons that are both equiangular and equilateral. All the sides that compose a regular polygon have the same length and are placed around a common center. This way, all the angles between any two sides are equal.

The following picture shows the six regular polygons and the generalized formulas that we can use to calculate their perimeters and areas. The generalized formula to calculate the area requires us to calculate a cotangent, which is abbreviated as cot in the formula.

Tip

In Java 9, the Math class doesn't provide a method to directly calculate a cotangent. However, it provides a method to calculate a tangent: Math.tan. The cotangent of x is equal to 1 pided by the tangent of x: 1/ Math.tan(x). Thus, we can easily calculate the cotangent with this formula.

As the three shapes use the same formula with just a different value for the number of sides (n) parameter, we can generalize the required interface for the six regular polygons. The interface is a special class named RegularPolygon that defines a new getSidesCount method that returns the number of sides with an integer value. The RegularPolygon class is a subclass of the previously defined Shape class. It makes sense because a regular polygon is indeed a shape. The six classes that represent regular polygons become subclasses of RegularPolygon. However, both the calculateArea and calculatePerimeter methods are coded in the RegularPolygon class using the generalized formulas. The subclasses code the getSidesCount method to return the right value, as follows:

  • EquilateralTriangle: 3
  • Square: 4
  • RegularPentagon: 5
  • RegularHexagon: 6
  • RegularOctagon: 8
  • RegularDecagon: 10

The RegularPolygon class also defines the lengthOfSide property that was previously defined in the three classes that represent regular polygons. Now, the six classes become subclasses of RegularPolygon and inherit the lengthOfSide property. The following figure shows an updated version of the UML diagram with the new RegularPolygon class and the changes in the six classes that represent regular polygons. The six classes that represent regular polygons do not declare either the calculateArea or calculatePerimeter methods because these classes inherit them from the RegularPolygon superclass and don't need to make changes to these methods that apply a general formula.

The diagram shows the results of the fourth round.

When we analyzed ellipses, we mentioned that there was a problem when calculating its perimeter. We talked with our domain expert and he provided us with detailed information about the issue. There are many formulas that provide approximations of the perimeter value for this shape. It makes sense to add additional methods that calculate the perimeter using other formulas. He suggested us to make it possible to calculate the perimeters with the following formulas:

  • A formula proposed by David W. Cantrell
  • A second version of the formula developed by Srinivasa Aiyangar Ramanujan

We will define the following two additional parameterless methods to the Ellipse class. The new methods will return a floating point value and solve the specific problem of the ellipse shape:

  • calculatePerimeterWithRamanujanII
  • calculatePerimeterWithCantrell

This way, the Ellipse class will implement the methods specified in the Shape superclass and also add two specific methods that aren't included in any of the other subclasses of Shape. The following figure shows an updated version of the UML diagram with the new methods for the Ellipse class.

The diagram shows the results of the fifth round: