From 51e0aeb4994acbbaae717d2d7a05f8df6442a23c Mon Sep 17 00:00:00 2001 From: Tamer Tas Date: Fri, 15 Apr 2016 14:51:23 +0300 Subject: [PATCH] Refactor strategy pattern --- README.md | 2 +- behavioral/strategy.md | 55 +++++++++++++++++++++++++++++++++++++++ strategy/strategy.go | 25 ------------------ strategy/strategy_test.go | 18 ------------- 4 files changed, 56 insertions(+), 44 deletions(-) create mode 100644 behavioral/strategy.md delete mode 100644 strategy/strategy.go delete mode 100644 strategy/strategy_test.go diff --git a/README.md b/README.md index 3d10126..abc0113 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ __Behavioral Patterns__: | [Observer](observer.go) | Provide a callback for notification of events/changes to data | | [Registry](registry.go) | Keep track of all subclasses of a given class | | [State](state.go) | Encapsulates varying behavior for the same object based on its internal state | -| [Strategy](strategy/strategy.go) | Enables an algorithm's behavior to be selected at runtime | +| [Strategy](behavioral/strategy.md) | Enables an algorithm's behavior to be selected at runtime | | [Template](template.go) | Defines a skeleton class which defers some methods to subclasses | | [Visitor](visitor.go) | Separates an algorithm from an object on which it operates | diff --git a/behavioral/strategy.md b/behavioral/strategy.md new file mode 100644 index 0000000..e04e683 --- /dev/null +++ b/behavioral/strategy.md @@ -0,0 +1,55 @@ +#Strategy Pattern +Strategy behavioral design pattern enables an algorithm's behavior to be selected at runtime. + +It defines algorithms, encapsulates them, and uses them interchangeably. + +## Implementation +Implementation of an interchangeable operator object that operates on integers. + +```go +type Operator interface { + Apply(int, int) int +} + +type Operation struct { + Operator Operator +} + +func (o *Operation) Operate(leftValue, rightValue int) int { + return o.Operator.Apply(leftValue, rightValue) +} +``` + +## Usage +### Addition Operator +```go +type Addition struct{} + +func (Addition) Apply(lval, rval int) int { + return lval + rval +} +``` + +```go +add := Operation{Addition{}} +add.Operate(3, 5) // 8 +``` + +### Multiplication Operator +```go +type Multiplication struct{} + +func (Multiplication) Apply(lval, rval int) int { + return lval * rval +} +``` + +```go +mult := Operation{Multiplication{}} + +mult.Operate(3, 5) // 15 +``` + +## Rules of Thumb +- Strategy pattern is similar to Template pattern except in its granularity. +- Strategy pattern lets you change the guts of an object. Decorator pattern lets you change the skin. diff --git a/strategy/strategy.go b/strategy/strategy.go deleted file mode 100644 index 09a5d81..0000000 --- a/strategy/strategy.go +++ /dev/null @@ -1,25 +0,0 @@ -package strategy - -type Operator interface { - Apply(int, int) int -} - -type Operation struct { - Operator Operator -} - -func (o *Operation) Operate(leftValue, rightValue int) int { - return o.Operator.Apply(leftValue, rightValue) -} - -type Multiplication struct{} - -func (Multiplication) Apply(lval, rval int) int { - return lval * rval -} - -type Addition struct{} - -func (Addition) Apply(lval, rval int) int { - return lval + rval -} diff --git a/strategy/strategy_test.go b/strategy/strategy_test.go deleted file mode 100644 index deadd4f..0000000 --- a/strategy/strategy_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package strategy - -import "testing" - -func TestMultiplicationStrategy(t *testing.T) { - mult := Operation{Multiplication{}} - - if res := mult.Operate(3, 5); res != 15 { - t.Errorf("Multiplication.Operate(3, 5) expected 15 got %q", res) - } -} - -func TestAdditionStrategy(t *testing.T) { - add := Operation{Addition{}} - if res := add.Operate(3, 5); res != 8 { - t.Errorf("Addition.Operate(3, 5) expected 8 got %q", res) - } -}