Consider the following abstract class MeasurementType
and its subtypes Acceleration
and Density
:
public abstract class MeasurementType {
protected String name;
protected String[] units;
public MeasurementType() {}
public MeasurementType(String name) {
this.name = name;
}
protected void setName(String name) {
this.name = name;
}
protected String getName() {
return name;
}
protected void setUnits(String[] values) {
this.units = values;
}
}
public class Acceleration extends MeasurementType {
private String name;
public Acceleration () {
super();
}
public Acceleration(String name) {
super();
}
}
public class Density extends MeasurementType {
private String name;
public Density() {
super();
}
public Density(String name) {
super();
}
}
What is the need for the subtypes are since there isn't anything in those classes that differentiates them apart enough (at least in my implementations) to give them the right to exist as their own entities, but for the sake of the example, lets say they had their own arrays containing units for each distinct type, so density would have kilograms, grams etc.. and acceleration would have mph, kmph etc..
Finally I have this run class which I quickly made up:
public class run {
public run() {}
public static MeasurementType testType() {
Acceleration a = new Acceleration("meters per second");
return (MeasurementType) a;
}
public static void main(String[] args) {
MeasurementType mt = testType();
System.out.println(mt.getClass().toString());
System.out.println(mt.getClass().getName());
String type = "acceleration";
String[] units = new String[8];
Object mType;
if(type.equals("acceleration")) {
mType = new Acceleration();
} else if(type.equals("density")) {
mType = new Density();
} else {
mType = new Object();
}
System.out.println(mType.getName());
}
}
This is where i encountered the problem that I was thinking about. I was using strings to determine the type that I would instantiate, but the problem is, by default right at the end of the conditional statements I instantiate Object because otherwise the compiler would complain that the mType
variable wouldn't have been initialized. I can't create a MeasurementType
object since it is an abstract class.
I guess this is more of a design question, but is there a better way of determining the class to instantiate? Please assume that the String type = "acceleration"
came from a drop down or somewhere from some user interface, I have just hard coded it in because it isn't really necessary for the question.
Could someone shed some light on this design fault as I see it please.
As the name suggests, this principle states that software entities should be open for extension, but closed for modification. As a result, when the business requirements change then the entity can be extended, but not modified.
In object-oriented programming, the open–closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can allow its behaviour to be extended without modifying its source code.
Note that the Decorator design pattern follows the Open Closed Principle, one of the SOLID principles. Incidentally, the Open Closed Principle is used to design classes that are open for extensions but closed for modifications.
For example, the Decorator pattern offers us to follow the Open Close principle. Furthermore, we may use the Factory Method, Strategy pattern and the Observer pattern to design an application with minimum changes in the existing code. That's all about 'SOLID Principles : The Open Closed Principle'.
Looking at the crux of your question, what to do when the string is neither "acceleration" or "density".
if(type.equals("acceleration")) {
mType = new Acceleration();
} else if(type.equals("density")) {
mType = new Density();
} else {
mType = new Object();
}
Is this a sign that something in your program has broken, that it is irretrievable wrong? In which case; throw an exception.
if(type.equals("acceleration")) {
mType = new Acceleration();
} else if(type.equals("density")) {
mType = new Density();
} else {
throw new RuntimeException("variable type is not a valid type, valid types are 'acceleration' and 'density'";
}
This is a realisation you will come to; exceptions are your friend. They mean when the program is wrong it screams where and why and then you fix it. On the other hand quietly ignoring the problem leads to subtle bugs and strange behaviour that can take days to diagnose.
On the other hand is this a sign of the user entering inappropriate input? In that case, validate the input and if its invalid tell the end user and ask for it again.
Using String
s and if statements like this is likely not to be what you want to do at all, but under the assumption it is what you want to do then this is the way forward (a switch statement would be slightly nicer).
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