mirror of
https://github.com/tmrts/go-patterns.git
synced 2024-11-21 20:46:08 +03:00
add state, composite pattern
This commit is contained in:
parent
16eeba3b73
commit
d1a1cd4725
@ -26,7 +26,7 @@ A curated collection of idiomatic design & application patterns for Go language.
|
||||
| Pattern | Description | Status |
|
||||
|:-------:|:----------- |:------:|
|
||||
| [Bridge](/structural/bridge.md) | Decouples an interface from its implementation so that the two can vary independently | ✘ |
|
||||
| [Composite](/structural/composite.md) | Encapsulates and provides access to a number of different objects | ✘ |
|
||||
| [Composite](/structural/composite.md) | Encapsulates and provides access to a number of different objects | ✔ |
|
||||
| [Decorator](/structural/decorator.md) | Adds behavior to an object, statically or dynamically | ✔ |
|
||||
| [Facade](/structural/facade.md) | Uses one type as an API to a number of others | ✘ |
|
||||
| [Flyweight](/structural/flyweight.md) | Reuses existing instances of objects with similar/identical state to minimize resource usage | ✘ |
|
||||
@ -42,7 +42,7 @@ A curated collection of idiomatic design & application patterns for Go language.
|
||||
| [Memento](/behavioral/memento.md) | Generate an opaque token that can be used to go back to a previous state | ✘ |
|
||||
| [Observer](/behavioral/observer.md) | Provide a callback for notification of events/changes to data | ✔ |
|
||||
| [Registry](/behavioral/registry.md) | Keep track of all subclasses of a given class | ✘ |
|
||||
| [State](/behavioral/state.md) | Encapsulates varying behavior for the same object based on its internal state | ✘ |
|
||||
| [State](/behavioral/state.md) | Encapsulates varying behavior for the same object based on its internal state | ✔ |
|
||||
| [Strategy](/behavioral/strategy.md) | Enables an algorithm's behavior to be selected at runtime | ✔ |
|
||||
| [Template](/behavioral/template.md) | Defines a skeleton class which defers some methods to subclasses | ✘ |
|
||||
| [Visitor](/behavioral/visitor.md) | Separates an algorithm from an object on which it operates | ✘ |
|
||||
|
59
behavioral/state.md
Normal file
59
behavioral/state.md
Normal file
@ -0,0 +1,59 @@
|
||||
# Strategy Pattern
|
||||
Strategy behavioral design pattern allow an object alter its behavior when its internal state changes. The object will appear on change its class.
|
||||
|
||||
## Implementation
|
||||
```go
|
||||
package state
|
||||
type State interface {
|
||||
executeState(c *Context)
|
||||
}
|
||||
|
||||
type Context struct {
|
||||
StepIndex int
|
||||
StepName string
|
||||
Current State
|
||||
}
|
||||
|
||||
type StartState struct{}
|
||||
|
||||
func (s *StartState) executeState(c *Context) {
|
||||
c.StepIndex = 1
|
||||
c.StepName = "start"
|
||||
c.Current = &StartState{}
|
||||
}
|
||||
|
||||
type InprogressState struct{}
|
||||
|
||||
func (s *InprogressState) executeState(c *Context) {
|
||||
c.StepIndex = 2
|
||||
c.StepName = "inprogress"
|
||||
c.Current = &InprogressState{}
|
||||
}
|
||||
|
||||
type StopState struct{}
|
||||
|
||||
func (s *StopState) executeState(c *Context) {
|
||||
c.StepIndex = 3
|
||||
c.StepName = "stop"
|
||||
c.Current = &StopState{}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
context := &Context{}
|
||||
var state State
|
||||
|
||||
state = &StartState{}
|
||||
state.executeState(context)
|
||||
fmt.Println("state: ", context)
|
||||
|
||||
state = &InprogressState{}
|
||||
state.executeState(context)
|
||||
fmt.Println("state: ", context)
|
||||
|
||||
state = &StopState{}
|
||||
state.executeState(context)
|
||||
fmt.Println("state: ", context)
|
||||
```
|
68
structural/composite.md
Normal file
68
structural/composite.md
Normal file
@ -0,0 +1,68 @@
|
||||
# Composite Pattern
|
||||
Composite structural pattern allows composing objects into a tree-like structure and work with the it as if it was a singular object.
|
||||
|
||||
## Interface
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type file struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (f *file) search(keyword string) {
|
||||
fmt.Printf("Searching for keyword %s in file %s\n", keyword, f.name)
|
||||
}
|
||||
|
||||
func (f *file) getName() string {
|
||||
return f.name
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation
|
||||
`search` function will operate applies to both files and folders. For a file, it will just look into the contents of the file; for a folder, it will go through all files of that folder to find that keyword.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type folder struct {
|
||||
components []component
|
||||
name string
|
||||
}
|
||||
|
||||
func (f *folder) search(keyword string) {
|
||||
fmt.Printf("Serching recursively for keyword %s in folder %s\n", keyword, f.name)
|
||||
for _, composite := range f.components {
|
||||
composite.search(keyword)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *folder) add(c component) {
|
||||
f.components = append(f.components, c)
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
```go
|
||||
file1 := &file{name: "File1"}
|
||||
file2 := &file{name: "File2"}
|
||||
file3 := &file{name: "File3"}
|
||||
|
||||
folder1 := &folder{
|
||||
name: "Folder1",
|
||||
}
|
||||
|
||||
folder1.add(file1)
|
||||
|
||||
folder2 := &folder{
|
||||
name: "Folder2",
|
||||
}
|
||||
folder2.add(file2)
|
||||
folder2.add(file3)
|
||||
folder2.add(folder1)
|
||||
|
||||
folder2.search("rose")
|
||||
```
|
Loading…
Reference in New Issue
Block a user