A Curious Mind
#tastic

Strategy Pattern

Thursday, August 02, 2007 5:56 AM

So I am getting ready to write up some code that needs to do some daily processing every day except for the first of the month where it needs to do some additional work. It first I had a method that looked something like this:

public void RoutineMaintenance()
{
  if(isFirstOfTheMonth)
  {
    ImportDataFromThirdPartySources();
  }
  GenerateInvoices();
  CheckOverduePayments();
  UpdateTransactionsFromPaymentSource();
  if(isFirstOfTheMonth)
  {
    ExportDataToThirdPartySources();
  }
}

So what I don't like about this is the double 'if's. I know that it can be a minor issue but I see it as cluttering up the code. So after thinking about it I thought, I could use the strategy pattern + the decorator pattern to better implement this code.

public interface DailyProcess { void Perform(); }
public class StandardProcess : DailyProcess
{
  public void Perform()
  {
    GenerateInvoices();
    CheckOverduePayments();
    UpdateTransactionsFromPaymentSource();
  }
}

public class FirstBusinessDayOfTheMonth : DailyProcess
{
  DailyProcess innerProcess;
  public FirstBusinessDayOfTheMonth(DailyProcess innerProcess)
  {
    this.innerProcess = innerProcess;
  }
  
  public void Perform()
  {
    ImportDataFromThirdPartySources();
    innerProcess.Perform();
    ExportDataToThirdPartySources();
  }
}

public class RoutineMaintenance
{
  DailyProcess process;
  public RoutineMaintenance(DailyProcess process)
  {
    this.process = process;
  }
  
  public void PerformDailyProcess()
  {
    process.Perform();
  }
}

This "improvement" uses a lot more code and you can cleary see that it adds complexity, but now I can easily configure RoutineMaintenance do handle a variety of tasks by just loading up the daily process. My new code being called might look like

Dictionary<bool, DailyProcess> processes = new Dictionary<bool, DailyProcess>();
processes.Add(true, new new FirstBusinessDayOfTheMonth(new DailyProcess()));
processes.Add(false, new DailyProcess());

//later in the app

RoutineMaintenance maint = new RoutineMaintenance(processes[isFirstBusinessDayOfTheMonth]);
maint.PerformDailyProcess();

This kind of stuff is a lot easier with frameworks like Castle, and Spring.


Feedback

# re: Strategy Pattern

>> public interface DailyProcess ...

An interface that doesn't start with 'I' - that sir is blasphemy! Other than that, I like what you've done here.

I've been reading up on Spring.net the over past couple of days and so far I like what I'm seeing... but it sure seems like a whole lot of (way to verbose) angle-bracket meta-programming to me. In your experience, does that hold true? 8/9/2007 9:20 AM | Steven Harman

# re: Strategy Pattern

I do so like to stir the pot. ;)

I much prefer Castle.MicroKernel / Windsor (very succinct I think) to Spring.Net (too verbose for me as well) but as long as you are using one or the other I will be happy. ;) 8/9/2007 9:51 AM | Dru

# re: Strategy Pattern

Ok... so when using Windsor do you typically use it in conjunction with MonoRail?

I'm looking for an MVC framework as I'm sick of WebForms and the total lack of testability - so Spring.net and MonoRail seem to be the leading contenders right now. Though I've seen several posts about the recently released ProMesh.net framework... but I'm not sold, yet.

Thoughts, suggestions... words of advice? 8/9/2007 9:57 AM | Steven Harman

# re: Strategy Pattern

Personally I am a HUGE fan of MonoRail. It just makes sense to me. Also, I love the way they think about development in general.

-d 8/9/2007 12:25 PM | Dru

Comments have been closed on this topic.