Inspired by this question, I played a bit with the idea of modeling a Triangle, and a utility method to classify it:
class Triangle {
private final int a;
private final int b;
private final int c;
enum Type {
EQUILATERAL, INVALID, ISOSCELES, SCALENE
}
public Triangle(int a, int b, int c) {
if (!isSaneArguments(a, b, c)) {
throw new IllegalArgumentException("All sides of a Triangle must be > 0");
}
if (!isTriangle(a, b, c)) {
throw new IllegalArgumentException("Not a triangle: no side must be longer than the sum of the other sides");
}
this.a = a;
this.b = b;
this.c = c;
}
private static boolean isSaneArguments(int a, int b, int c) {
return a > 0 && b > 0 && c > 0;
}
private static boolean isTriangle(int a, int b, int c) {
return a < b + c && b < a + c && c < a + b;
}
public static Type classifyValidTriangle(int a, int b, int c) {
final Type type;
if (a == b && b == c) {
type = Type.EQUILATERAL;
} else if (b == c || a == b || c == a) {
type = Type.ISOSCELES;
} else {
type = Type.SCALENE;
}
return type;
}
public static Type classify(int a, int b, int c) {
if (!isSaneArguments(a, b, c) || !isTriangle(a, b, c)) {
return Type.INVALID;
}
return classifyValidTriangle(a, b, c);
}
public Type classify() {
return classifyValidTriangle(a, b, c);
}
}
Unit tests:
public class TriangleTest {
@Test(expected = IllegalArgumentException.class)
public void testInvalidTriangleWithTooLongSide() {
int a = 1;
int b = a + 1;
new Triangle(a, b, a + b + 1);
}
@Test(expected = IllegalArgumentException.class)
public void testInvalidTriangleWithNegativeSide() {
new Triangle(1, 2, 0);
}
@Test
public void testScalene() {
assertEquals(Triangle.Type.SCALENE, new Triangle(2, 3, 4).classify());
assertEquals(Triangle.Type.SCALENE, Triangle.classify(2, 3, 4));
}
@Test
public void testEquilateral() {
assertEquals(Triangle.Type.EQUILATERAL, new Triangle(3, 3, 3).classify());
assertEquals(Triangle.Type.EQUILATERAL, new Triangle(2, 2, 2).classify());
assertEquals(Triangle.Type.EQUILATERAL, Triangle.classify(5, 5, 5));
}
@Test
public void testIsosceles() {
assertEquals(Triangle.Type.ISOSCELES, new Triangle(3, 3, 2).classify());
assertEquals(Triangle.Type.ISOSCELES, new Triangle(3, 2, 3).classify());
assertEquals(Triangle.Type.ISOSCELES, new Triangle(2, 3, 3).classify());
assertEquals(Triangle.Type.ISOSCELES, Triangle.classify(2, 3, 3));
assertEquals(Triangle.Type.ISOSCELES, Triangle.classify(3, 3, 2));
assertEquals(Triangle.Type.ISOSCELES, Triangle.classify(3, 2, 3));
}
}
What do you think? What would you do differently? How can it be better?
classifyValidTriangle
andclassify
are public, that's strange. – maaartinus yesterday