I've builded a 2D-shape area calculator. Currently it can only calculate:
- Circle
- Rectangle
- Triangle
Originally I was thinking how to encapsulate the parameter(s) into a class, Parameters, so that I could delegate the responsibility of loading those parameter(s) to a specific shape, for example, a rectangle will need a base and a height, to the Parameters class. Then finally I made it too complicated.
So instead, I try the following implementation. To focus on any better way to load the parameters and to update the area, I assumed the input of the user is correct.
Any advice about the pros and cons of my implementation is appreciated. Any other way to solve my problem is appreciated, also.
UML:
Edit: I made all setters return this
so I can set a Rectangle, r
, like this: r.setHeight(20.).setWidth(10.)
, so you don't have to care which parameter comes first.(r.getArea()
will return 200).
Source Code:
Shape.java
public abstract class Shape {
protected double area;
public double getArea() {
return area;
}
protected abstract void onAreaChange();
}
Triangle.java
public class Triangle extends Shape {
protected double base;
protected double height;
public Triangle setBase(double base) {
this.base = base;
onAreaChange();
return this;
}
public Triangle setHeight(double height) {
this.height = height;
onAreaChange();
return this;
}
@Override
public void onAreaChange() {
this.area = 0.5 * this.base * this.height;
}
}
Rectangle.java
public class Rectangle extends Shape {
protected double height;
protected double width;
public Rectangle setHeight(double height) {
this.height = height;
onAreaChange();
return this;
}
public Rectangle setWidth(double width) {
this.width = width;
onAreaChange();
return this;
}
@Override
public void onAreaChange() {
this.area = this.height * this.width;
}
}
Circle.java
public class Circle extends Shape {
protected double radius;
protected final double PI = 3.14159265;
public Circle setRadius(double radius) {
this.radius = radius;
onAreaChange();
return this;
}
@Override
public void onAreaChange() {
this.area = this.radius * this.radius * PI;
}
}
Main.java
import java.util.Scanner;
public class Main {
public static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
while (true) {
System.out.println("Enter the number which you want to compute the area");
System.out.print("(1) Triangle (2) Rectangle (3) Circle ? ");
switch (scan.nextInt()) {
case 1:
Triangle triangle = new Triangle();
System.out.print("Base: ");
triangle.setBase(scan.nextDouble());
System.out.print("Height: ");
triangle.setHeight(scan.nextDouble());
System.out.println("Area of triangle: " + triangle.getArea());
break;
case 2:
Rectangle rectangle = new Rectangle();
System.out.print("Width: ");
rectangle.setWidth(scan.nextDouble());
System.out.print("Height: ");
rectangle.setHeight(scan.nextDouble());
System.out.println("Area of rectangle: " + rectangle.getArea());
break;
case 3:
Circle circle = new Circle();
System.out.print("Radius: ");
circle.setRadius(scan.nextDouble());
System.out.println("Area of circle: " + circle.getArea());
break;
default:
System.out.println("What do u mean?");
}
}
}
}
onAreaChange
the idea of reactive programming comes to mind... \$\endgroup\$