It's natural if you think calmly, but I thought about it for a moment, so as a memo ...
I'll omit the Getter / Setter, but there is a Square class that has vertical and horizontal lengths in the fields.
Square.java
public class Square {
private int width;
private int height;
}
If you make it possible to set the value using Builder and create a class that returns the area at the end, it will be as follows.
SquareBuilder.java
public class SquareBuilder {
public static class Builder {
Square square = new Square();
public Builder() {}
public Builder width(int width) {
square.setWidth(width);
return this;
}
public Builder height(int height) {
square.setHeight(height);
return this;
}
public int build() {
return square.getWidth() * square.getHeight();
}
}
}
Then, you can find the area like this
Main.java
public class Main {
public static void main(String[] args) {
SquareBuilder.Builder squareBuilder = new SquareBuilder.Builder();
System.out.println("Area is:" + squareBuilder.width(5).height(10).build());
}
}
There is no particular problem so far. : slight_smile:
Next, create a Cube class that inherits from Square. (Omit Getter / Setter.)
Cube.java
public class Cube extends Square {
private int depth;
}
Aside from whether the height was depth ...: kissing:
It also inherits Builder
CubeBuilder.java
public class CubeBuilder extends SquareBuilder {
public static class Builder extends SquareBuilder.Builder {
private Cube cube = new Cube();
public Builder() {}
public Builder depth(int depth) {
cube.setDepth(depth);
return this;
}
@Override
public int build() {
return super.build() * cube.getDepth();
}
}
}
Then, you can find the volume like this.
Main.java
public class Main {
public static void main(String[] args) {
CubeBuilder.Builder cubeBuilder = new CubeBuilder.Builder();
System.out.println("Volume is:" + cubeBuilder.depth(2).width(5).height(10).build());
}
}
This code goes through compilation and requires volume, but it's actually a problem.
You have to call depth () first to find the volume. : worried:
The reason is that the return values of width () and height () are of type SquareBuilder.Builder, so you can't calldepth (), which is defined only in CubeBuilder.Builder. ..
We will use Generics here.
Reference: Subclassing a Java Builder class
SquareBuilder.java
public class SquareBuilder {
public static class Builder<T extends Builder<T>> {
Square square = new Square();
public Builder() {}
public T width(int width) {
square.setWidth(width);
return (T) this;
}
public T height(int height) {
square.setHeight(height);
return (T) this;
}
public int build() {
return square.getWidth() * square.getHeight();
}
}
}
CubeBuilder.java
public class CubeBuilder extends SquareBuilder {
public static class Builder extends SquareBuilder.Builder<Builder> {
private Cube cube = new Cube();
public Builder() {}
public Builder depth(int depth) {
cube.setDepth(depth);
return this;
}
@Override
public int build() {
return super.build() * cube.getDepth();
}
}
}
As a result, the return type of width () and height () will be a class that inherits SquareBuilder.Builder instead of SquareBuilder.Builder, so you need to calldepth ()first. lose.
Main.java
public class Main {
public static void main(String[] args) {
SquareBuilder.Builder squareBuilder = new SquareBuilder.Builder();
System.out.println("Area is:" + squareBuilder.width(5).height(10).build());
CubeBuilder.Builder cubeBuilder = new CubeBuilder.Builder();
System.out.println("Volume is:" + cubeBuilder.width(5).height(10).depth(2).build());
}
}
However, I feel a little uncomfortable because there is a Warning. : mask:
It's a program that puts values in POJOs with a lot of fields and outputs them in JSON format, so it became troublesome to put values in Setter one by one, and I was addicted to using Builder.
In this example, the area cannot be calculated, but Warning can be eliminated by making SquareBuilder an abstract class.
SquareBuilder.java
public class SquareBuilder {
public abstract static class Builder<T extends Builder<T>> {
Square square = new Square();
public Builder() {}
public abstract T getThis();
public T width(int width) {
square.setWidth(width);
return getThis();
}
public T height(int height) {
square.setHeight(height);
return getThis();
}
public int build() {
return square.getWidth() * square.getHeight();
}
}
}
CubeBuilder.java
public class CubeBuilder extends SquareBuilder {
public static class Builder extends SquareBuilder.Builder<Builder> {
private Cube cube = new Cube();
public Builder() {}
@Override
public Builder getThis() {
return this;
}
public Builder depth(int depth) {
cube.setDepth(depth);
return this;
}
@Override
public int build() {
return super.build() * cube.getDepth();
}
}
}
Recommended Posts