-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
678 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# 迭代器模式 | ||
|
||
## 概念 | ||
|
||
用于顺序访问集合对象的元素,不需要知道集合对象的底层表示 | ||
|
||
## 模式的场景和优缺点 | ||
|
||
### 使用场景 | ||
|
||
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示 | ||
|
||
### 优点 | ||
|
||
- 迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。 | ||
|
||
### 缺点 | ||
|
||
- 状态模式的使用必然会增加系统类和对象的个数 | ||
- 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱 | ||
- 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码 | ||
|
||
## 代码实现 | ||
|
||
```golang | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
// Aggregate ... | ||
type Aggregate interface { | ||
Iterator() Iterator | ||
} | ||
|
||
// Iterator ... | ||
type Iterator interface { | ||
First() | ||
IsDone() bool | ||
Next() interface{} | ||
} | ||
|
||
// Numbers 实现了 Iterator | ||
type Numbers struct { | ||
start, end int | ||
} | ||
|
||
// NewNumbers ... | ||
func NewNumbers(start, end int) *Numbers { | ||
return &Numbers{ | ||
start: start, | ||
end: end, | ||
} | ||
} | ||
|
||
// Iterator 生成一个可迭代对象 | ||
func (n *Numbers) Iterator() Iterator { | ||
return &NumbersIterator{ | ||
numbers: n, | ||
next: n.start, | ||
} | ||
} | ||
|
||
// NumbersIterator 实现了 Iterator | ||
type NumbersIterator struct { | ||
numbers *Numbers | ||
next int | ||
} | ||
|
||
// First ... | ||
func (i *NumbersIterator) First() { | ||
i.next = i.numbers.start | ||
} | ||
|
||
// IsDone ... | ||
func (i *NumbersIterator) IsDone() bool { | ||
return i.next > i.numbers.end | ||
} | ||
|
||
// Next ... | ||
func (i *NumbersIterator) Next() interface{} { | ||
if !i.IsDone() { | ||
next := i.next | ||
// i 变成下一个 | ||
i.next++ | ||
return next | ||
} | ||
return nil | ||
} | ||
|
||
// IteratorPrint ... | ||
func IteratorPrint(i Iterator) { | ||
for i.First(); !i.IsDone(); { | ||
c := i.Next() | ||
fmt.Printf("%#v\n", c) | ||
} | ||
} | ||
|
||
func main() { | ||
|
||
var aggregate Aggregate | ||
aggregate = NewNumbers(1, 10) | ||
|
||
IteratorPrint(aggregate.Iterator()) | ||
} | ||
|
||
|
||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# 责任链模式 | ||
|
||
## 概念 | ||
|
||
责任链模式(Chain of Responsibility Pattern)用于分离不同职责,并且动态组合相关职责 | ||
|
||
## 模式的场景和优缺点 | ||
|
||
### 使用场景 | ||
|
||
在处理消息的时候以过滤很多道 | ||
|
||
### 优点 | ||
|
||
- 降低耦合度。它将请求的发送者和接收者解耦 | ||
- 简化了对象。使得对象不需要知道链的结构 | ||
- 增强给对象指派职责的灵活性 | ||
- 通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任 | ||
- 增加新的请求处理类很方便 | ||
|
||
### 缺点 | ||
|
||
- 不能保证请求一定被接收 | ||
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用 | ||
- 可能不容易观察运行时的特征,有碍于除错 | ||
|
||
## 代码实现 | ||
|
||
```golang | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
// Manager 定义接口 | ||
type Manager interface { | ||
HaveRight(money int) bool | ||
HandleFeeRequest(name string, money int) bool | ||
} | ||
|
||
// RequestChain 职责链 | ||
type RequestChain struct { | ||
Manager | ||
successor *RequestChain | ||
} | ||
|
||
// SetSuccessor 设置处理者 | ||
func (r *RequestChain) SetSuccessor(m *RequestChain) { | ||
|
||
r.successor = m | ||
} | ||
|
||
// HandleFeeRequest 调用链路会调用处理者 | ||
func (r *RequestChain) HandleFeeRequest(name string, money int) bool { | ||
if r.Manager.HaveRight(money) { | ||
return r.Manager.HandleFeeRequest(name, money) | ||
} | ||
if r.successor != nil { | ||
return r.successor.HandleFeeRequest(name, money) | ||
} | ||
return false | ||
} | ||
|
||
// HaveRight ... | ||
func (r *RequestChain) HaveRight(money int) bool { | ||
return true | ||
} | ||
|
||
// ProjectManager ... | ||
type ProjectManager struct { | ||
Name string | ||
} | ||
|
||
// NewProjectManagerChain ... | ||
func NewProjectManagerChain(name string) *RequestChain { | ||
return &RequestChain{ | ||
Manager: &ProjectManager{Name: name}, | ||
} | ||
} | ||
|
||
// HaveRight ... | ||
func (p *ProjectManager) HaveRight(money int) bool { | ||
return money < 500 | ||
} | ||
|
||
// HandleFeeRequest ... | ||
func (p *ProjectManager) HandleFeeRequest(name string, money int) bool { | ||
if name == "bob" { | ||
fmt.Printf("Project manager permit %s %d fee request\n", name, money) | ||
return true | ||
} | ||
fmt.Printf("Project manager don't permit %s %d fee request\n", name, money) | ||
return false | ||
} | ||
|
||
// DepManager ... | ||
type DepManager struct { | ||
Name string | ||
} | ||
|
||
// NewDepManagerChain ... | ||
func NewDepManagerChain(name string) *RequestChain { | ||
return &RequestChain{ | ||
Manager: &DepManager{Name: name}, | ||
} | ||
} | ||
|
||
// HaveRight ... | ||
func (d *DepManager) HaveRight(money int) bool { | ||
return money < 5000 | ||
} | ||
|
||
// HandleFeeRequest ... | ||
func (d *DepManager) HandleFeeRequest(name string, money int) bool { | ||
fmt.Printf("my name:%s\n", d.Name) | ||
if name == "tom" { | ||
fmt.Printf("Dep manager permit %s %d fee request\n", name, money) | ||
return true | ||
} | ||
fmt.Printf("Dep manager don't permit %s %d fee request\n", name, money) | ||
return false | ||
} | ||
|
||
// GeneralManager ... | ||
type GeneralManager struct { | ||
Name string | ||
} | ||
|
||
// NewGeneralManagerChain ... | ||
func NewGeneralManagerChain(name string) *RequestChain { | ||
return &RequestChain{ | ||
Manager: &GeneralManager{Name: name}, | ||
} | ||
} | ||
|
||
// HaveRight ... | ||
func (g *GeneralManager) HaveRight(money int) bool { | ||
return true | ||
} | ||
|
||
// HandleFeeRequest ... | ||
func (g *GeneralManager) HandleFeeRequest(name string, money int) bool { | ||
fmt.Printf("my name:%s\n", g.Name) | ||
if name == "ada" { | ||
fmt.Printf("General manager permit %s %d fee request\n", name, money) | ||
return true | ||
} | ||
fmt.Printf("General manager don't permit %s %d fee request\n", name, money) | ||
return false | ||
} | ||
func main() { | ||
c1 := NewProjectManagerChain("c1") | ||
c2 := NewDepManagerChain("c2") | ||
c3 := NewGeneralManagerChain("c3") | ||
|
||
//c1 ---> c2 ----> c3 | ||
c1.SetSuccessor(c2) | ||
c2.SetSuccessor(c3) | ||
|
||
var c Manager = c1 | ||
|
||
c.HandleFeeRequest("bob", 400) | ||
c.HandleFeeRequest("tom", 1400) | ||
c.HandleFeeRequest("ada", 10000) | ||
c.HandleFeeRequest("floar", 400) | ||
} | ||
|
||
``` |
Oops, something went wrong.