1
0
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:
DH 2022-02-13 20:13:51 +09:00
parent 16eeba3b73
commit d1a1cd4725
3 changed files with 129 additions and 2 deletions

View File

@ -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
View 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
View 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")
```