I'm new to the concept of object oriented programming (in java) and I often encounter the following design problem:
I often create classes with instance variables which are not known at the moment of initialization. These variables are filled over time. This is not a real problem since these variables are null until they are filled, my question therefore is more about the best practice in such situations.
Let me explain it with an example. I have a class Car
. Every Car
has a color
, vMax
, weight
, horsepower
etc.
When initializing the Car
only it's color
, weight
and horsepower
are known. --> Car(color, weight, horsepower)
The vMax
can now be calculated (let's say: weight/horsepower
). What confuses me is, that the Car
, after initialization is "incomplete", meaning that the vMax
will only be filled over time.
I found this quite ugly, and of course the car-example is simplified. I often have classes with 10+ properties where some are calculated over time, which themselves later in the code are used to calculate even more properties of that object. It then becomes difficult to know which variables are already filled at a certain point and which are not.
I just wondered whether this is "normal" and the way OOP works, or whether such situations should be avoided. If yes, I'd be glad for some design-hints.
Michael
Instance variables persist as long as there are variables referencing them. PHP internally stores a reference count on each object. When an variable goes out of scope, PHP decrements the refcount and checks for 0. If it's 0, it cleans up the instance and destroys the object.
Because they are unnecessary but they will still float around in your views. The catch is, you know that they are unnecessary so you won't care about them (even if they contain wrong data) but next developers won't know that they are unnecessary.
Instance variables are declared without static keyword. Instance variables can be used only via object reference. Class variables can be used through either class name or object reference.
The lifetime of an instance variable is until the object stays in memory.
As you define vMax
should be a method
more than an attribute of the class:
class Car {
private String color;
private double weight;
private double horsePower;
// constructor for Car
public Car (String color, double weight, double horsePower) {
this.color = color;
this.weight= weight;
this.horsePower= horsePower;
}
// usually I would create this as one-line-method... but to clarify:
public double getVMax() {
double vMax = weight / horsePower; // calculate vMax!!!
return vMax;
}
}
It all depends on what you need.
The very first thing that comes to my mind is to use builder (especially taken into account that you mentioned "classes with 10+ properties")
The main idea of the builder is you don't create an object, until you know/calculate all its properties.
Let's get back to your car example.
class Car
{
final int weight;
final int horsepower;
final int vMax;
final String color;
private Car(int weight, int horsepower, int vMax, String color)
{
this.weight = assetNotNull(weight);
this.horsepower = assetNotNull(horsepower);
this.vMax = assetNotNull(vMax);
this.color = assetNotNull(color);
}
//..... other car-related methods
/** Car builder */
public static class Builder
{
int weight;
int horsepower;
int vMax;
String color;
public Builder setWeight(int weight)
{
this.weight = weight;
return this;
}
public Builder setHorsepower(int horsepower)
{
this.horsepower = horsepower;
return this;
}
public Builder setvMax(int vMax)
{
this.vMax = vMax;
return this;
}
public Builder setColor(String color)
{
this.color = color;
return this;
}
public Car createCar()
{
return new Car(weight, horsepower, vMax, color)
}
}
}
Then you can build your car like this
Car.Builder builder = new Car.Builder();
Car car = builder.setColor("blue")
.setHorsepower(10)
.setvMax(100)
.setWeight(1000)
.createCar();
This approach has the next benefits:
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With