Refactor strategy pattern

This commit is contained in:
Tamer Tas 2016-04-15 14:51:23 +03:00
parent 3885b01c61
commit 51e0aeb499
4 changed files with 56 additions and 44 deletions

View File

@ -45,7 +45,7 @@ __Behavioral Patterns__:
| [Observer](observer.go) | Provide a callback for notification of events/changes to data | | [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 | | [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 | | [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 | | [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 | | [Visitor](visitor.go) | Separates an algorithm from an object on which it operates |

55
behavioral/strategy.md Normal file
View File

@ -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.

View File

@ -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
}

View File

@ -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)
}
}