Add decorator pattern

This commit is contained in:
Tamer Tas 2016-04-15 15:35:27 +03:00
parent c0937dd592
commit d90a201871
3 changed files with 42 additions and 25 deletions

View File

@ -28,7 +28,7 @@ __Structural Patterns__:
| [Adapter](adapter.go) | Adapts otherwise incompatible interfaces to work together by adapting one to the other |
| [Bridge](bridge.go) | Decouples an interface from its implementation so that the two can vary independently |
| [Composite](composite.go) | Encapsulates and provides access to a number of different objects |
| [Decorator](decorator.go) | Adds behavior to an object, statically or dynamically |
| [Decorator](structural/decorator.md) | Adds behavior to an object, statically or dynamically |
| [Facade](facade.go) | Uses one class as an API to a number of others |
| [Flyweight](flyweight.go) | Reuses existing instances of objects with similar/identical state to minimize resource usage |
| [Model View Controller](mvc.go) | Divides an app into three interconnected parts to separate internal representation from presentation to user |

View File

@ -1,24 +0,0 @@
package main
import (
"fmt"
"log"
)
func LogDecorate(fn func(s string)) func(s string) {
return func(s string) {
log.Println("Starting the execution with the argument", s)
fn(s)
log.Println("Execution is completed.")
}
}
func Function(s string) {
fmt.Println(s)
}
func main() {
f := LogDecorate(Function)
f("Hello Decorator")
}

41
structural/decorator.md Normal file
View File

@ -0,0 +1,41 @@
# Decorator Pattern
Decorator structural pattern allows extending the function of an existing object dynamically without altering its internals.
Decorators provide a flexible method to extend functionality of objects.
## Implementation
`LogDecorate` decorates a function with the signature `func(int) int` that
manipulates integers and adds input/output logging capabilities.
```go
type Object func(int) int
func LogDecorate(fn Object) Object {
return func(n int) int {
log.Println("Starting the execution with the integer", n)
result := fn(n)
log.Println("Execution is completed with the result", result)
return result
}
}
```
## Usage
```go
func Double(n int) int {
return n * 2
}
f := LogDecorate(Double)
f(5)
// Starting execution with the integer 5
// Execution is completed with the result 10
```
## Rules of Thumb
- Unlike Adapter pattern, the object to be decorated is obtained by **injection**.
- Decorators should not alter the interface of an object.