Having three separate classes might make sense if you know you're going to add some special members to some of these subclasses and you just haven't gotten around to it yet (but you're going to really soon, right?).
Normally, I'd agree with the senior developer: This seems like an unecessary complication. Could you create an enumeration called Frequency
and use that to determine which type of Medication
you're dealing with, something like this pseudo-code:
Enum MedicationFrequency{MONTHLY, DAILY, WEEKLY, HOURLY}
class Medication
{
private MedicationFrequency frequency;
...
}
I suppose if you really want to keep the different implementations completely separate, you could try to inject specific algorithms into the Medication
instances. Maybe something like this:
Interface MedicationProcess
{
public void doSomething();
public String getWhen();
public MedicationFrequency getFreq();
}
class WeeklyMedProcess implements MedicationProcess
{
String weekdays;
public MedicationFrequency getFreqy() { return MedicationFrequency.WEEKLY;}
public String getWhen() { return weekdays; }
//...
}
class DailyMedProcess implements MedicationProcess
{
public MedicationFrequency getFreqy() { return MedicationFrequency.DAILY;}
//...
}
class MonthlyMedProcessimplements MedicationProcess
{
String monthdays;
public MedicationFrequency getFreqy() { return MedicationFrequency.MONTHLY;}
public String getWhen() { return monthdays; }
//...
}
class Medication
{
private MedicationProcess someProcess;
private String updateColumnName;
public void setUpdateColumnName(String s)
{
this.updateColumnName= s;
}
public void setProcess(MedicationProcess p)
{
this.someProcess = p;
}
public doMedicationThing()
{
this.someProcess.doSomething();
}
}
Doing this in Java, You'd have a Spring configuration that might look like this:
<bean id="dailyMedProc" class="DailyMedProcess/>
<bean id="weeklyMedProc" class="WeeklyMedProcess/>
<bean id="medication1" class="Medication">
<property name="process" ref="dailyMedProc/>
<property name="updateColumnName" value="weekdays"/>
</bean>
<bean id="medication" class="Medication">
<property name="process" ref="weeklyMedProc/>
<property name="updateColumnName" value="monthdays"/>
</bean>
To answer your quesion about weekdays
and monthdays
, there are many ways to do this and it's not very clear from your question just what weekdays
and monthdays
are. Since you show them to be single variables, I'll assume they are just comma-separate strings.
It sounds like you also have columns in some table named weekdays
and monthdays
which need to be set to null if there is no value. Since you already know the frequency of the Medication
(via its someProcess.getFreq
), you know which field to set to null. The implementors of MedicationProcess
can be required to implement getWhen
, which will return the comma-separated list of days/month-days. With these two pieces of information, you can easily update the correct columns.
Having Medication
have knowledge over what to do when specific MedicationFrequencies
are encountered does break the design pattern a little bit. It's not great, but it's a simple solution.
If you don't like that, you could include the column name that should be updated for a specific instance of Medication
. Only slightly better - I don't like mixing that sort of low-level data access into such classes, but I haven't seen the rest of your design, so maybe it's OK here...
Another option would be to have the MedicationProcess
do its own database insert/update. This is a little trickier and I can't really give any concrete examples of how to do this without knowing the details about your schema, though I think this would be the best solution, if you can implement it.
There are other ways to implement the strategy pattern, depending on the tools and frameworks available to you.
Also, see: https://stackoverflow.com/questions/17721623/advantages-of-using-strategy-pattern-in-php The question is PHP-specific, but the answer is not.
Medication
for point 1.Thanks for all your help