Click here to Skip to main content
15,884,388 members
Articles / All Topics

Refactor: Sequential Coupling => Template Method

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
15 Apr 2010CPOL2 min read 14.6K   1   1
Refactor: Sequential Coupling => Template Method

Another colleague brought me a present today - the blog post. Thank you. You were right!

We will do some refactoring which will lead us from Anti-Pattern to Pattern. From Sequential Coupling to Template Method. And as I see it could be a very common way to refactor bad code that represents mentioned anti-pattern.

So, let's start with the following question. What do you see to be wrong with following code?

C#
public class Manager
{
  public void DoTheProject()
  {
    IWorker worker = GetMeWorker();

    worker.PreWork();
    worker.Work();
    worker.AfterWork();
  }

Manager is a very angry guy and he needs to get the project done. For that, he would like to get some worker, which implements IWorker interface, and delegate some work to him. But also, manager knows that worker could be new to project so it will require to go ahead and do some preparational work before and maybe something to do after work is done...

What is wrong? Answer is that Manager cares too much about how worker should organize his work. Why should manager know that worker needs to be prepared for work? What we have here is the Sequential Coupling anti-pattern.

(My definition)

Sequential Coupling Anti-Pattern - appears when consuming code is forced to call methods of used object in particular sequence to make it work correctly.

If we call Work and then PreWork, code could be broken. And we want to prevent this. For example, we can move all that stuff in one method - Work, but also sometimes, it is needed to perform pre or/and after work, but sometimes not. That is why we had the following design that allowed us do this. See that StandardWorker doesn't need to do something after he has finished. This was achieved with virtual and abstract methods.

C#
public interface IWorker
{
  void PreWork();
  void Work();
  void AfterWork();
}

public abstract class WorkerBase : IWorker
{
  public virtual void PreWork(){}

  public abstract void Work();

  public virtual void AfterWork(){}
}

public class StandardWorker : WorkerBase
{
  public override void PreWork()
  {
    Console.WriteLine("... I need to prepare to work ...");
  }
  public override void Work()
  {
    Console.WriteLine("... hard work is in process ...");
  }
}

So, what we need to do is to hide the order in which we call methods, be sure that order remains the same, and still have the possibility to override each method. What I just described is Template Method.

In our example, we could leave one method in interface, then implement it in base class with calling everything else we need in the correct order, each of those things we call could be overridden, we left them protected to not show to the world.

C#
public interface IWorker
{
  void Work();
}

public abstract class WorkerBase : IWorker
{
  //this is template method
  public void Work()
  {
    PreWorkActivity();
    WorkActivity();
    AfterWorkActivity();
  }

  protected virtual void PreWorkActivity() { }
  protected abstract void WorkActivity();
  protected virtual void AfterWorkActivity() { }
}

public class StandardWorker : WorkerBase
{
  protected override void PreWorkActivity()
  {
    Console.WriteLine("... I need to prepare to work ...");
  }
  protected override void WorkActivity()
  {
    Console.WriteLine("... hard work is in process ...");
  }
}

public class Manager
{
  public void DoTheProject()
  {
    IWorker worker = GetMeWorker();

    worker.Work();
  }

  private IWorker GetMeWorker()
  {
    return new StandardWorker();
  }
}

It really looks for me that it could be common to perform refactoring from Sequential Coupling to Template Method.

Hope you liked this post.

This article was originally posted at http://andriybuday.blogspot.com/feeds/posts/default

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer SoftServe
Ukraine Ukraine
I'm very pragmatic and self-improving person. My goal is to become successful community developer.
I'm young and love learning, these are precondition to my success.

Currently I'm working in dedicated Ukrainian outsourcing company SoftServe as .NET developer on enterprise project. In everyday work I'm interacting with lot of technologies which are close to .NET (NHibernate, UnitTesting, StructureMap, WCF, Win/WebServices, and so on...)

Feel free to contact me.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Shabbazz14-Oct-10 18:11
professionalShabbazz14-Oct-10 18:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.