Published: 18 Aug 2008
By: Granville Barnett
Download Sample Code

Learn how to design more robust and maintainable code by incorporating design patterns into your software projects.

Contents [hide]

Introduction

Learning anything new often requires a little motivation. The premise of design patterns is simple – effective solutions to common design problems. Moreover these solutions have been battle tested in the field for many years. The result of this is that for many design scenarios there exists a design pattern.

Design Patterns Series

  • Part 1 Learn how to design more robust and maintainable code by incorporating design patterns into your software projects.
  • Part 2 This part shows the observer design pattern.
  • Part 3 In this part you will learn about the factory pattern.
  • Part 4 This part of the design patterns covers the singleton pattern.
  • Part 5 In this part of the design patterns series we investigate the command pattern and its uses.
  • Part 6 In this part of the design patterns series we will look at the adapter pattern.
  • Part 7 In this part of the design patterns series we will take a look at the template pattern.
  • Most design patterns are not trivial; they have taken someone (or a group of people) many hours to perfect. What is even more compelling is that they have published their work so you don’t have to waste your time solving the same problem.

    Design patterns differ to what could be considered primitive object oriented (OO) concepts. While they fully take advantage of everything that OO has to offer, they also introduce solutions that at the time may not be very obvious. As a direct result of this many who are very comfortable with OO don’t employ such patterns. Most are aware that OO principles can be used in many scenarios to design fairly elegant solutions to problems; however design patterns have a tendency to scale a lot better. Because design patterns scale gracefully while remaining simple to maintain you will find them used in many frameworks and applications.

    Throughout this series I will use UML diagrams to describe the structure of the design pattern in question. We will purposely avoid class diagrams so that others who are perhaps not familiar with the Microsoft development platforms can utilize this series. UML provides a common language that most developers, irrespective of their language and platform understand.

    In this series we will look at the most common design patterns. This part will cover a simple design pattern to emphasize the elegance of their application, and to act as motivation for reading the rest of this series.

    The strategy pattern

    The strategy pattern is built around being able to accommodate an interchangeable family of algorithms, or more aptly components. These components have varying implementations. One of the design principles’ is to separate everything that varies. The strategy pattern provides an elegant solution to such a problem.

    In this article we will look at a simple example. The example we will look at is based upon a car and its engine. Different cars have different engines; each engine behaves differently when its engine is started. Some engines will make you marvel at the engineering skills of man, others will make you curse them.

    Each car will have its own class, all car’s will derive from the abstract class Car.

    Figure 1: Basic outline of the class design structure

    Basic outline 

of the class design structure

    The main problem is that the engine varies for each car. The engine in a Ferrari Enzo is far different than that of a Ford Escort. What we have here is a very simple case of where the implementation will vary. All engines will exhibit slightly different behavior and so we want to separate this from that which doesn’t vary for all cars.

    At this stage let’s go ahead and design an interface (we’ll program to an interface here, not an implementation) which will define the behavior all engines must have. For our simple example, and to keep the focus on the pattern we will create an interface IEngine that only has one method Start.

    Figure 2: The IEngine interface

    The IEngine interface

    Now that we have our interface we will define an additional two types: EnzoEngine, and EscortEngine both of which will implement IEngine. We will also add an attribute to the Car class that is of type IEngine, as well as a Start method.

    Figure 3: Our final solution design

    Our final solution design

    Of course the example we are working through is very simple to keep focus on the actual pattern we are designing. In reality a Car type may have several other properties like the number of doors, the type of gearbox etc.

    So far we have not talked about the Start method in the Car class. This Start method will delegate the start engine behavior to the actual object. Ex: when we create a new instance of Enzo the Enzo class will initialize the value of m_engine to an EnzoEngine. When the Start method of Car is invoked the Start method of EnzoEngine will be called. Similarly in Escort the value of m_engine will be initialized to EscortEngine and its Start method will be invoked upon calling the Start method in Car. The implementation of this behavior is simple in Car, its Start method will contain the imperative m_engine.Start();

    We mentioned earlier that the strategy pattern enables the interchanging of a family of algorithms. In our example this family of algorithm is all the types that implement IEngine. For instance should our program require so we could upgrade the engine in our Escort and swap in an EnzoEngine at run time.

    Implementing our design

    Implementing the design we have discussed thus far is really very trivial. For purposes of illustration we will use a Console Application and print messages to the Console from both the EnzoEngine and EscortEngine Start methods to differentiate between the two.

    Listing 1: IEngine.cs

    Listing 2: EnzoEngine.cs

    Listing 3: EscortEngine.cs

    Listing 4: Car.cs

    Listing 5: Enzo.cs

    Listing 6: Escort.cs

    Listing 7: Program.cs

    Running the application results in the expected output – one car sounds like its amazing, the other making wished you had never bought it.

    Figure 4: Delegated behavior to the respective engine objects

    Delegated behavior to the respective engine objects

    Summary

    The strategy pattern allows for a family of interchangeable algorithms. These algorithms can be interchanged freely with no effect on the design; the correct behavior is delegated to the actual object. As demonstrated in this article all behavior that varies, e.g. the engines have been isolated from that which doesn’t vary. Each engine is programmed to an interface not an implementation, although you could use an abstract class.

    The beauty of the strategy pattern is its simplicity. We have a robust and maintainable design that can be further extended in the future, yet the design is incredibly simple.

    In the next article we will look at the observer pattern which is a lot more fun!

    <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    About Granville Barnett

    Sorry, no bio is available

    This author has published 32 articles on DotNetSlackers. View other articles or the complete profile here.

    Other articles in this category


    Introduction to StructureMap
    Have you heard of StructureMap, generally know what it’s for, and want to know how to get started qu...
    DI Patterns: Constructor Injection
    In this article, an excerpt from the book "Dependency Injection in .NET", we will take a detailed lo...
    The Command Pattern
    In this article I will provide a quick refresher on what the command pattern is used for, how it wor...
    TypeMock’s Arrange-Act-Assert
    Brian Mains discusses how to implement the Arrange-Act-Assert pattern in TypeMock.
    Key Process Patterns
    This article, based on chapter 2 of Specification by Example, presents effective patterns for softwa...

    You might also be interested in the following related blog posts


    Learn design patterns from real projects: JBoss case study (Part 1). read more
    Designing a Windows 8 Metro style app starting from an existing Windows Phone app Design Case Study Part 1 read more
    Oredev Wrap-Up read more
    Introducing SharePoint 2010 Training at U2U read more
    The Underground at PDC read more
    12 ASP.NET MVC Best Practices read more
    Screencast Whats new in the Entity Data Model Designer in VS2010 read more
    What needed to be monitored to get better Governance read more
    SharePoint 2010 Workflow read more
    Formatting Text in RadControls for WinForms Q3 2009 read more
    Top
     
     
     

    Discussion


    Subject Author Date
    placeholder Help! KC TSANG 4/28/2009 5:22 AM
    RE: Help! Sonu Kapoor 4/28/2009 8:24 AM
    placeholder RE: RE: Help! KC TSANG 4/28/2009 11:44 PM
    Great articles... Terry Keane 8/25/2008 11:35 AM
    placeholder RE: Great articles... Granville Barnett 8/25/2008 12:12 PM

    Please login to rate or to leave a comment.