The fact is that I wanted to apply the builder pattern. But this could not be achieved, since I could not create an instance of the class with an empty constructor - this is dangerous. The goal is to make the parameter list a little shorter and more meaningful. As a result, I created a new class, the builder, which sets all the fields that are in the class in the constructor.
Why don't I want to use a builder pattern? Because the user may not use the builder at all - the required fields will be blank.
GameObject:
public abstract class GameObject {
protected boolean isHidden;
protected Coordinate position;
protected int pictureWidth, pictureHeight;
protected Object filling;
GameObject(GameObjectBuilder gameObjectBuilder) throws IOException{
this.position = new Coordinate(gameObjectBuilder.getPosition());
this.pictureWidth = gameObjectBuilder.getPictureWidth();
this.pictureHeight = gameObjectBuilder.getPictureHeight();
this.isHidden = gameObjectBuilder.isHidden();
this.filling = gameObjectBuilder.getFilling(); // link is passed
}
public void paint(Graphics gr) throws IOException{
if(filling instanceof BufferedImage) {
gr.drawImage((Image) filling, position.getX(), position.getY(), null);
}
else if(filling instanceof Color) {
gr.setColor((Color) filling);
gr.fillRect(position.getX(), position.getY(), pictureWidth, pictureHeight);
} else {
System.err.println("You forgot to add a way to render filling");
}
}
private Object getFilling() {
return filling;
}
int getPictureWidth() {
return pictureWidth;
}
int getPictureHeight() {
return pictureHeight;
}
public boolean isHidden() {
return isHidden;
}
public Coordinate getPosition() {
return position;
}
}
GameObjectBuilder:
public class GameObjectBuilder {
protected boolean isHidden;
protected Coordinate position;
protected int pictureWidth, pictureHeight;
public Object filling;
public GameObjectBuilder(int pictureWidth, int pictureHeight, Coordinate position, boolean isHidden, Color filling){
this.position = new Coordinate(position);
this.pictureWidth = pictureWidth;
this.pictureHeight = pictureHeight;
this.isHidden = isHidden;
this.filling = filling; // link
}
public GameObjectBuilder(Coordinate position, boolean isHidden, BufferedImage filling){
this.position = position;
this.pictureWidth = filling.getWidth();
this.pictureHeight = filling.getHeight();
this.isHidden = isHidden;
this.filling = filling; // передается ссылка
}
public GameObjectBuilder(GameObjectBuilder gameObject) throws IOException{
this.position = new Coordinate(gameObject.getPosition());
this.pictureWidth = gameObject.getPictureWidth();
this.pictureHeight = gameObject.getPictureWidth();
this.isHidden = gameObject.isHidden();
this.filling = gameObject.getFilling(); //link is passed
}
public Object getFilling() {
return filling;
}
public int getPictureWidth() {
return pictureWidth;
}
public int getPictureHeight() {
return pictureHeight;
}
public boolean isHidden() {
return isHidden;
}
public Coordinate getPosition() {
return position;
}
}
and now for dessert:
MaterialGameObject:
public abstract class MaterialGameObject extends GameObject{
private int materialHeight, materialWidth;
private Coordinate relativeCoordinateOfStartOfFilling;
public MaterialGameObject(MaterialGameObjectBuilder materialGameObjectBuilder) throws IOException{
super(materialGameObjectBuilder.getGameObjectBuilder());
this.materialHeight = materialGameObjectBuilder.getMaterialHeight();
this.materialWidth = materialGameObjectBuilder.getMaterialWidth();
calculateRelativeCoordinateOfStartOfFilling();
}
private int getMaterialWidth() {
return materialWidth;
}
public int getMaterialHeight() {
return materialHeight;
}
public Coordinate getRelativeCoordinateOfStartOfFilling() {
return relativeCoordinateOfStartOfFilling;
}
protected abstract void calculateRelativeCoordinateOfStartOfFilling();
}
MaterialGameObjectBuilder:
public class MaterialGameObjectBuilder{
private GameObjectBuilder gameObjectBuilder;
private int materialHeight, materialWidth;
public MaterialGameObjectBuilder(GameObjectBuilder gameObjectBuilder, int materialHeight, int materialWidth) {
this.gameObjectBuilder = gameObjectBuilder; // link
this.materialHeight = materialHeight;
this.materialWidth = materialWidth;
}
public GameObjectBuilder getGameObjectBuilder(){
return gameObjectBuilder;
}
public int getMaterialHeight() {
return materialHeight;
}
public int getMaterialWidth() {
return materialWidth;
}
}
Did I choose the right path?