Search code examples
javafactory-pattern

Java - how to tell an object to use a set of parameters from a different method


I'm working on an exercise which simulates an air traffic control tower with weather tracking features.

I have a coordinates class which has a private constructor. The constructor takes 3 arguments, longitude, latitude and height. An aircraft class which takes with the arguments Coordinates coordinates and name. The aircraft class is inherited by 3 classes JetPlane, Helicopter and Baloon whose constructors take the same arguments as Aircraft.

As part of the exercise I have to use a factory class to create any of the 3 objects. My problem is that the factory method takes as arguments name, type, longitude, latitude and height but the objects which it returns ask for a Coordinates object.

How can I tell it that it should take the parameters from the factory class to make the Coordinates object? I have tried with a makeCoordinates method but if I set it to static that all coordinates will be 0. Is there any way to call it without it being static and without having to create a Coordinates object?

As part of the exercise I am not allowed to remove or add any parameters and access specifiers or change their type. So the Coordinates constructor will have to remain private.

(Flyable is an interface with a register and update method)

Here is the Coordinates class

public class Coordinates {
private int longitude;
private int latitude;
private int height;

public int getLongitude() {
    return longitude;
}
public void setLongitude(int longitude) {
    this.longitude = longitude;
}
public int getLatitude() {
    return latitude;
}
public void setLatitude(int latitude) {
    this.latitude = latitude;
}
public int getHeight() {
    return height;
}
public void setHeight(int height) {
    this.height = height;
}

private Coordinates(int latitude, int longitude, int height){
}

public static Coordinates makeCoordinate(int longitude, int latitude, int height) {
    return new Coordinates(longitude, latitude, height);
}

}

The factory class

public class ConcreteAircraftFactory extends AircraftFactory {

public Flyable newAircraft (String type, String name, int longitude, int latitude, int height){


    Coordinates coord = Coordinates.makeCoordinate(longitude, latitude, height);


    if (type.equals("Baloon") || type.equals("baloon")) {
        return new Baloon(name, coord);

    }

    else if(type.equals("JetPlane") || type.equals("jetplane") || type.equals("Jetplane")) {
        return new JetPlane(name, coord);

    }

    else if(type.equals("Helicopter") || type.equals("helicopter")) {
        return new Helicopter(name, coord);

    }
    else
        return null;

}

}

The Aircraft class

public class Aircraft {

protected long  Id; 
protected String name;
protected Coordinates coordinates;
private long idCounter;

public long getId() {
    return Id;
}
public void setId(long id) {
    Id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public Coordinates getCoordinates() {
    return coordinates;
}
public void setCoordinates(Coordinates coordinates) {
    this.coordinates = coordinates;
}
public long getIdCounter() {
    return idCounter;
}
public void setIdCounter(long idCounter) {
    this.idCounter = idCounter;
}
public Aircraft( String name, Coordinates coordinates) {

    this.name = name;
    this.coordinates = coordinates;
}

private long nextId() {
    Id = getIdCounter() +1;
    idCounter++;
    return Id;
}

}

And one of the 3 classes which inherit Aircraft

public class Baloon extends Aircraft  implements Flyable {

private WeatherTower weatherTower;
private String text;

public Baloon( String name, Coordinates coordinates) {
    super( name, coordinates);
}

public void updateConditions() {
    String newWeather = weatherTower.getWeather(coordinates);


    switch(newWeather) {

    case WeatherType.FOG: 
        coordinates.setHeight(coordinates.getHeight()-3);
        text ="Baloon #" + this.getName() + "(" + this.getId() + "): get us lower, we are flying through pea soup";
        try(PrintWriter out = new PrintWriter("Simulation.txt")){
            out.println(text);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        break;

    case WeatherType.RAIN:
        coordinates.setHeight(coordinates.getHeight()-5);
        text ="Baloon #" + this.getName() + "(" + this.getId() + "): descending will not make us any less wet";
        try(PrintWriter out = new PrintWriter("Simulation.txt")  ){
            out.println(text);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        break;

    case WeatherType.SUN:
        coordinates.setHeight(coordinates.getHeight()+4);
        coordinates.setLongitude(coordinates.getLongitude()+2);
        text ="Baloon #" + this.getName() + "(" + this.getId() + "): make twoards the rising sun";
        try(PrintWriter out = new PrintWriter("Simulation.txt")  ){
            out.println(text);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        break;


    case WeatherType.SNOW:
        coordinates.setHeight(coordinates.getHeight()-15);
        text ="Baloon #" + this.getName() + "(" + this.getId() + "): this thing does not run a cold air";
        try(PrintWriter out = new PrintWriter("Simulation.txt")  ){
            out.println(text);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        break;
    }
    if(coordinates.getHeight()<0) {
        coordinates.setHeight(0);
    }
    if(coordinates.getHeight()>100) {
        coordinates.setHeight(100);
    }
    if (coordinates.getHeight()==0) {
        weatherTower.unregister(this);
        String text ="Tower Says: Baloon #" + this.getName() + "(" + this.getId() + "): has been unrergistered";
        try(PrintWriter out = new PrintWriter("Simulation.txt")  ){
            out.println(text);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

public void registerTower(WeatherTower weatherTower) {
    weatherTower.register(this);
    text ="Tower Says: Baloon #" + this.getName() + "(" + this.getId() + "): registered to weather tower";
    try(PrintWriter out = new PrintWriter("Simulation.txt")  ){
        out.println(text);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

}
}

Solution

  • Actually the factory method of Coordinates invokes the Coordinates private constructor but it has an empty body.
    So it doesn't value any field of Coordinates :

    private Coordinates(int latitude, int longitude, int height){
    }
    

    Just set the fields of the currently created object with the passed parameters :

    private Coordinates(int latitude, int longitude, int height){
       this.latitude = latitude;
       this.longitude= longitude;
       this.height= height;
    }