43
Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Embed Size (px)

Citation preview

Page 1: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Go4 Template Method, Strategy, State Patterns

Presented By:Matt Wilson

Page 2: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Introduction

2

This presentation originated out of casual talk between former WMS “C++ Book Club” (defunct program) developers who wanted to continue to get together on occasion to discuss technical topics.

It’s expected that all Senior Software Engineers understand the G04 Design Patterns well, and thus their occasional review is useful.

Page 3: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Introduction

3

This Presentation Series was created to not only teach what the patterns are, but explain best-practices of when and why you would want to use them

Sources used here included the Gang of 4 Design Patterns Book, Head First Design Patterns book, and many online articles and discussion boards on the topic.

Page 4: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method

4

Page 5: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use Template Method?

5

Good news: Template Method is an Easy/Simple effective G04 pattern to learn.

Very commonly used Design Pattern. Template Method is a Non-Virtual class’ Method that calls one or

more other of the class’ methods that are Virtual. Subclasses override the Class with the Template Method, and

implement their own behavior for the Virtual methods. A Herb Sutter Guideline for good OO design:

Prefer to make interfaces nonvirtual, using Template Method.

Gives benefits with little to no downside. http://www.gotw.ca/publications/mill18.htm

Page 6: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use Template Method?

6

Formal definition:Template Method: “Define the skeleton of an algorithm in an

operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. ”

Like other G04 Pattern descriptions, it’s very technical/complicated sounding, but it actually very straightforward.

Page 7: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method – UML

7

Page 8: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Benefits

8

• A single class owns the Algorithm. SubClasses don’t need to know about it anymore.

• Eliminates duplicate code across SubClasses, maximizing reuse.• Provides a Framework for SubClass extension.

• Use Template Method whenever you want to create a method for SubClasses to implement.

Page 9: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Example (C#)

9

abstract class DataAccessObject { protected string connectionString; protected DataSet dataSet; public virtual void Connect() { // Make sure mdb is available to app connectionString = "provider=Microsoft.JET.OLEDB.4.0; " + "data source=..\\..\\..\\db1.mdb"; } public abstract void Select(); public abstract void Process(); public virtual void Disconnect() { connectionString = ""; } // The 'Template Method' public void Run() { Connect(); Select(); Process(); Disconnect(); } }

Page 10: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Example (C#)

10

class Categories : DataAccessObject { public override void Select() { string sql = "select CategoryName from Categories"; OleDbDataAdapter dataAdapter = new OleDbDataAdapter( sql, connectionString); dataSet = new DataSet(); dataAdapter.Fill(dataSet, "Categories"); } public override void Process() { Console.WriteLine("Categories ---- "); DataTable dataTable = dataSet.Tables["Categories"]; foreach (DataRow row in dataTable.Rows) { Console.WriteLine(row["CategoryName"]); } Console.WriteLine(); } }

Page 11: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Example (C#)

11

class Products : DataAccessObject { public override void Select() { string sql = "select ProductName from Products"; OleDbDataAdapter dataAdapter = new OleDbDataAdapter( sql, connectionString); dataSet = new DataSet(); dataAdapter.Fill(dataSet, "Products"); } public override void Process() { Console.WriteLine("Products ---- "); DataTable dataTable = dataSet.Tables["Products"]; foreach (DataRow row in dataTable.Rows) { Console.WriteLine(row["ProductName"]); } Console.WriteLine(); } }

Page 12: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Example (C#)

12

class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main() { DataAccessObject daoCategories = new Categories(); daoCategories.Run(); DataAccessObject daoProducts = new Products(); daoProducts.Run(); // Wait for user Console.ReadKey(); } }

Page 13: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Example (C#) - OUTPUT

13

Categories ----BeveragesCondimentsConfectionsDairy ProductsGrains/CerealsMeat/PoultryProduceSeafood

Products ----ChaiChangAniseed SyrupChef Anton's Cajun SeasoningChef Anton's Gumbo MixGrandma's Boysenberry SpreadUncle Bob's Organic Dried PearsNorthwoods Cranberry SauceMishi Kobe Niku

Page 14: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Herb Sutter Tips - Virtuality

14

As referenced earlier, Herb Sutter is an advocate of Template Method. See the link for details.

In summary, his Guidelines for C++ development regarding this pattern are the following:

#1: Prefer to make interfaces nonvirtual, using Template Method.

#2: Prefer to make virtual functions private.#3: Only if derived classes need to invoke the base

implementation of a virtual function, make the virtual function protected.

#4: A base class destructor should be either public and virtual (common), or protected and nonvirtual (rare).

Page 15: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Template Method Questions ?

15

Page 16: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern

16

Page 17: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use Strategy Pattern?

17

When C++ Guru’s (Sutter, Myers, etc.) tell us:“Prefer Composition over Inheritance”, it’s a mistake to simply believe that they mean ”Inheritance is bad” and discourage its use in your designs. That is not what they mean.

What they are actually telling us, is to implement the Strategy Pattern!

Why are they telling us to use it? Because Strategy Pattern is a more flexible, Composition alternative to Inheritance.

Page 18: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use Strategy Pattern?

18

Formal definition: “The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.”

In other words: The Strategy Pattern allows you to dynamically change the code Methods execute during run time.

Page 19: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use Strategy Pattern?

19

Instead of utilizing Inheritance to encapsulate different behaviors inside different SubTypes, it uses Composition to encapsulate different behaviors inside member variables.

Strategy Pattern is useful for eliminating fragile if-else/switch code.

Note: Strategy Pattern is very similar to State Pattern (more on this later)

Page 20: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern - UML

20

Strategy Pattern uses Inheritance to enable Composition:

Page 21: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern – SOLID Design Principles

21

• Strategy Pattern is in harmony with SOLID Design Principles for good OO Design

• Open Closed Principle• Open for extension, but closed for modification• Or as I like to put it: Writing new code shouldn’t require a

change to existing code• As new behaviors are needed, new Strategies can be created

without effecting any existing code.• Dependency Inversion Principle:

• Classes shouldn’t have references to Concrete Classes• Violation creates dependency problems, longer compile times,

and prohibits Unit Testing/dependency injection.

Page 22: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern – SOLID Design Principles

22

• Strategy Pattern also helps keep the interface of SuperClasses clean and uncluttered from needing to have methods that don’t belong on some SubClasses.

• Example: Should fly() be a method on a CBirdClass? Some bird Subclasses can’t fly! Instead, use Strategy Pattern to define a flyBehavior() interface.

Page 23: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern – Example (Java)

23

/// <summary>  /// The 'Strategy' abstract class  /// </summary>  abstract class SortStrategy  {    public abstract void Sort(List<string> list);  }

Page 24: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern – Example (Java)

24

  class QuickSort : SortStrategy  {    public override void Sort(List<string> list)    {      list.Sort(); // Default is Quicksort      Console.WriteLine("QuickSorted list ");    }  }   class ShellSort : SortStrategy  {    public override void Sort(List<string> list)    {      ShellSort(list);       Console.WriteLine("ShellSorted list ");    }  }   class MergeSort : SortStrategy  {    public override void Sort(List<string> list)    {      MergeSort(list);      Console.WriteLine("MergeSorted list ");    }  }

Page 25: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern – Example (Java)

25

class SortedList   {

// NOTE: INSTEAD OF HAVING MULTIPLE SUBCLASSES OF SortedList, // you only have one that contains a dynamic strategy/behavior.

    private List<string> _list = new List<string>();    private SortStrategy _sortstrategy;     public void SetSortStrategy(SortStrategy sortstrategy)    {      this._sortstrategy = sortstrategy;    }     public void Add(string name)    {      _list.Add(name);    }     public void Sort()    {      _sortstrategy.Sort(_list);       // Iterate over list and display results      foreach (string name in _list)      {        Console.WriteLine(" " + name);      }      Console.WriteLine();    }  }

Page 26: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern – Example (Java)

26

class MainApp  {    /// <summary>    /// Entry point into console application.    /// </summary>    static void Main()    {      // Two contexts following different strategies      SortedList studentRecords = new SortedList();       studentRecords.Add("Samual");      studentRecords.Add("Jimmy");      studentRecords.Add("Sandra");      studentRecords.Add("Vivek");      studentRecords.Add("Anna");       studentRecords.SetSortStrategy(new QuickSort());      studentRecords.Sort();       studentRecords.SetSortStrategy(new ShellSort());      studentRecords.Sort();       studentRecords.SetSortStrategy(new MergeSort());      studentRecords.Sort();       // Wait for user      Console.ReadKey();    }  }

Page 27: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern vs. Template Method

27

Strategy Pattern & Template Method have some things in common.

Both patterns provide clients a way to execute different behavior, based on using different Types that encapsulate different behavior.

However, Temple Method enables this through Inheritance, while Strategy enables it though Composition.

Template Method provides a concrete method that “owns” the algorithm, whereas in Strategy pattern, there is no “owner” of an algorithm. You may or may not prefer an “owner” depending upon the context of your specific needs.

Strategy is more in line with SOLID dependency inversion principles, and is more flexible, however using Template Method may give you simpler designs which is also important.

Basic rule of thumb:• Use Template Method whenever you are creating Virtual Methods.• Use Strategy Pattern whenever you want to change class behavior at runtime, without the

use of Inheritance.

Page 28: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Strategy Pattern Questions ?

28

Page 29: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

State Pattern

29

Page 30: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use State Pattern?

30

The Go4 State Pattern is an OO way to create a State Machine in software.

Definition of State Machine: “A state machine, is a model used to design both computer

programs and sequential logic circuits. It can be in one of a finite number of states. The machine is in only one state at a time; the state it is in at any given time is called the current state. It can change from one state to another when initiated by a triggering event or condition; this is called a transition. A state machine is defined by a list of its states, and the triggering condition for each transition.”

Page 31: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

State Machine Model Example:

31

Page 32: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use State Pattern?

32

Why implement a State Machine? State machines are incredibly useful for modeling and

implementing complex processes. It enables your program/state-machine to change its behavior

during runtime, such that different code executes in Methods based on the current State of the machine.

State Pattern is useful for eliminating fragile if-else/switch code.

Page 33: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use State Pattern?

33

Without a State Machine: CYourClass::DoSomething()

{ if (x) then dox(); else if (y) then do(y)… etc. }

With a State Machine CYourClass::DoSomething()

{ state->doit():

} // CLEAN extensible OO - good SOLID Principles:

Page 34: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

What-is/Why-use State Pattern?

34

Does this Pattern sound Familiar? “Enables your program to change its behavior during runtime”

“Pattern is useful for eliminating fragile if-else/switch code.”

?

Well let’s look at the UML? Does this look familiar?

Page 35: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

State Pattern - UML

35

Page 36: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

State Pattern UML

36

Compare to Strategy Pattern UML

Page 37: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

State Pattern vs. Strategy Pattern

37

The State Pattern has the same UML Structure as the Strategy Pattern. So is it the same Pattern?

Practically yes, but Technically no.

A “State” and a “Strategy” can be looked at as the same thing, a class owned via composition, that encapsulates different behaviors.

When WMS had OO Training, the teacher said these two patterns “can be looked at as the same thing”, and that is true in regards to their Structure. However the difference is in implementation details.

The State Pattern “is-a” or “type-of” Strategy Pattern, but State Pattern adds State Machine logic to drive the setting of the current States/Strategies.

The main difference:• In Strategy Pattern, the composited Strategies/States are changed at runtime typically by the

client who wants control over what Strategy/State they want to use.• In State Pattern, the composited States/Strategies are not changed by the client, but by the

rules of the State Machine enforced in code.

Page 38: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Simple State Pattern Example (C#)

38

using System;

class MainApp { static void Main() { // Setup context in a state Context c = new Context(new ConcreteStateA());

// Issue requests, which toggles state c.Request(); c.Request(); c.Request(); c.Request();

// Wait for user Console.Read(); } }

Page 39: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Simple State Pattern Example (C#)

39

// "State" abstract class State { public abstract void Handle(Context context); }

// "ConcreteStateA" class ConcreteStateA : State { public override void Handle(Context context) { context.State = new ConcreteStateB(); } }

// "ConcreteStateB" class ConcreteStateB : State { public override void Handle(Context context) { context.State = new ConcreteStateA(); } }

Page 40: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Simple State Pattern Example (C#)

40

// "Context" class Context { private State state; // THIS IS THE Composited State/Strategy

// Constructor public Context(State state) { this.State = state; }

// Property public State State { get{ return state; } set { state = value; Console.WriteLine("State: " + state.GetType().Name); } }

public void Request() { state.Handle(this); } }

Page 41: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

Simple State Pattern Example (C#)

41

Output:

State: ConcreteStateAState: ConcreteStateBState: ConcreteStateAState: ConcreteStateBState: ConcreteStateA

Page 42: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

State Pattern

42

Most of the time to create a State pattern, you will begin by creating a State UML diagram for your States and their Transitions, then implement the rules in code.

Many tools exist that generate code from State Diagrams.

Page 43: Go4 Template Method, Strategy, State Patterns Presented By: Matt Wilson

State Pattern Questions ?

43