Apply polymorphism or you will drive yourself crazy
public class Psychiatrist
{
private final Pharmacy pharmacy;
private Psychiatrist(Pharmacy pharmacy)
{
this.pharmacy = pharmacy;
}
public Prescription takeCare(MultiplePersonality personality)
{
// MultiplePersonality may have been created with a
// String, Integer or just a Boolean
// try to get a String from MultiplePersonality object
String string = personality.areYouAString();
if (string != null) {
this.pharmacy.isAString(string);
return this.pharmacy.getPrescription();
}
// or try to get an Integer from MultiplePersonality object
Integer integer = personality.areYouAnInteger();
if (integer != null) {
this.pharmacy.isAnInteger(integer);
return this.pharmacy.getPrescription();
}
// or try to get just a Boolean from MultiplePersonality object
Boolean nuts = personality.areYouNuts();
if (nuts == null) {
throw new RuntimeException();
}
return null;
}
}
/**
* Instead use this
*/
public class Psychiatrist
{
private final Pharmacy pharmacy;
private Psychiatrist(Pharmacy pharmacy)
{
this.pharmacy = pharmacy;
}
public Prescription takeCare(Personality personality) {
return this.pharmacy.getPrescription(personality);
}
}
public class Pharmacy
{
public void isAString(String string)
{
}
public void isAnInteger(Integer integer)
{
}
public Prescription getPrescription(Personality personality)
{
personality.whatAreYou(this);
//decide upon prescription
}
}
/**
* With a Personality for each
*/
public class IntegerPersonality implements Personality
{
private final Integer integer;
private IntegerPersonality(Integer integer)
{
this.integer = integer;
}
@Override
public void whatAreYou(Pharmacy pharmacy) {
pharmacy.isAnInteger(this.integer);
}
}
public class StringPersonality implements Personality
{
private final String string;
private StringPersonality(String string)
{
this.string = string;
}
@Override
public void whatAreYou(Pharmacy pharmacy) {
pharmacy.isAString(this.string);
}
}
public class SanePersonality implements Personality
{
@Override
public void whatAreYou(Pharmacy pharmacy) {
throw new RuntimeException("I'm sane!");
}
}
Don’t try to do to much. (Class Relationships). Identify polymorphism in 3 steps. (How to identify polymorphism)?
- find the common operation (e.g. #whatAreYou)
- find how is every operation different and put it in a method in each own class (e.g. #isAString, #isAnInteger, “is nuts”)
- introduce an interface for the above classes with that common method
That’s all really. Try it with a Calculator example now.
Using polymorphism will
- eliminate the need for multiple if(s)
- eliminate the check for null
- eliminate the exceptional case (in this case to return null)
Plus on each Personality class you get
- final fields
- single responsibility
- encapsulation
Disclaimer: This is actual (disguised) code as seen on a very popular API. There are even more problems to discuss about it but let’s just focus on one thing at a time.