意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
// 处理事件
type ScreenEvent struct {
Type string
Comment string
}
// 定义处理事件的方法
type IScreenEventHandler interface{
Handle(*ScreenEvent)bool
SetNextHandler(IScreenEventHandler)
}
// 兜底处理器
type AbsScreenEventHandler struct {
NextHandler IScreenEventHandler
}
func(ase *AbsScreenEventHandler)Handle(se *ScreenEvent)bool{
if ase.NextHandler!=nil {
return ase.NextHandler.Handle(se)
}
return false
}
func(ase *AbsScreenEventHandler)SetNextHandler(ise IScreenEventHandler){
ase.NextHandler=ise
}
type HomeScreenEventHandler struct {
AbsScreenEventHandler
}
func(hse *HomeScreenEventHandler)Handle(se *ScreenEvent)bool{
fmt.Println("HomeScreenEventHandler.....")
if se.Type=="HomeClick" {
fmt.Println("HomeClick")
return true
}
return hse.AbsScreenEventHandler.Handle(se)
}
type UserScreenEventHandler struct {
AbsScreenEventHandler
}
func(use *UserScreenEventHandler)Handle(se *ScreenEvent)bool{
fmt.Println("UserScreenEventHandler.....")
if se.Type=="UserModelClick" {
fmt.Println("UserModelClick")
return true
}
return use.AbsScreenEventHandler.Handle(se)
}
var (
osd IScreenEventHandler
)
func init() {
osd=&AbsScreenEventHandler{}
home:=&HomeScreenEventHandler{}
user:=&UserScreenEventHandler{}
// 设置下一个责任链
home.SetNextHandler(user)
osd.SetNextHandler(home)
}
func TestChainOfResponsibility(t *testing.T) {
screenEvent:=&ScreenEvent{Type:"HomeClick"}
osd.Handle(screenEvent)
//fmt.Println("-----------------------------------------------\n")
screenEvent=&ScreenEvent{Type:"UserModelClick"}
osd.Handle(screenEvent)
//fmt.Println("-----------------------------------------------\n")
screenEvent=&ScreenEvent{Type:"Null"}
osd.Handle(screenEvent)
}
意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
如何解决:通过调用者调用接受者执行命令,顺序:调用者→命令→接受者。
// 命令接口
type Command interface {
Do(args interface{}) (interface{}, error)
}
// Get 命令
type GetCommand struct {
}
func (gc *GetCommand) Do(args interface{}) (interface{}, error) {
fmt.Println("GetCommand")
return args, nil
}
// post 命令
type PostCommand struct {
}
func (pc *PostCommand) Do(args interface{}) (interface{}, error) {
fmt.Println("PostCommand")
return args, nil
}
// 命令管理者
type CommandHandler struct {
CmdMap map[string]Command
}
// 注册命令
func (ch *CommandHandler) Register(cmdType string, cmd Command) {
ch.CmdMap[cmdType] = cmd
}
// 处理上下文
type CmdContext struct {
CmdType string
Args interface{}
}
// 处理命令
func (ch *CommandHandler) Handle(ctx *CmdContext) (interface{}, error) {
if ctx == nil {
return nil, errors.New("")
}
cmd, ok := ch.CmdMap[ctx.CmdType]
if ok {
return cmd.Do(ctx.Args)
}
return nil, errors.New("invalid Command ")
}
// 命令接口
type Command interface {
Do(args interface{}) (interface{}, error)
}
var (
// 命令处理者
cmdHandler = &CommandHandler{CmdMap: make(map[string]Command)}
)
func init() {
cmdHandler.Register("post", &PostCommand{})
cmdHandler.Register("get", &GetCommand{})
}
func TestCommand(t *testing.T) {
postCtx := &CmdContext{CmdType: "post", Args: " Post"}
getCtx := &CmdContext{CmdType: "get", Args: " Get"}
nullCtx := &CmdContext{CmdType: "null", Args: " Get"}
fmt.Println(cmdHandler.Handle(postCtx))
fmt.Println(cmdHandler.Handle(getCtx))
fmt.Println(cmdHandler.Handle(nullCtx))
}
// 表达式接口
type Expression interface {
Interpret(context string) bool
}
// 终结符
type TerminalExpression struct {
Word string
}
func(te *TerminalExpression)Interpret(context string) bool{
if strings.Contains(context,te.Word) {
return true
}
return false
}
// 或
type OrExpression struct {
A Expression
B Expression
}
func(oe *OrExpression)Interpret(context string) bool{
return oe.A.Interpret(context)||oe.B.Interpret(context)
}
// 与
type AndExpression struct {
A Expression
B Expression
}
func(ae *AndExpression )Interpret(context string) bool{
return ae.A.Interpret(context)&&ae.B.Interpret(context)
}
func TestInterpreterTest(t *testing.T) {
isMale :=&OrExpression{&TerminalExpression{"Robert"},&TerminalExpression{"John"}}
isMarriedWoman :=&AndExpression{&TerminalExpression{"Julie"},&TerminalExpression{"Married"}}
fmt.Println("John is male?",isMale.Interpret("John"))
fmt.Println("Julie is a married women?",isMarriedWoman.Interpret("Married Julie"))
}
这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
// 迭代器接口
type Iterator interface {
HasNext() bool
Next() interface{}
}
// 集合接口
type Container interface {
GetIterator() Iterator
}
// 数组迭代器
type ArrayIterator struct {
currentIndex int
ac *ArrayContainer
}
func (ai *ArrayIterator) HasNext() bool {
if ai.ac.arrayData!=nil&&ai.currentIndex < len(ai.ac.arrayData) {
return true
}
return false
}
func (ai *ArrayIterator) Next() interface{} {
if ai.HasNext() {
defer func() { ai.currentIndex++ }()
return ai.ac.arrayData[ai.currentIndex]
}
return nil
}
// 数组集合
type ArrayContainer struct {
arrayData []interface{}
}
func (ac *ArrayContainer) GetIterator() Iterator {
return &ArrayIterator{currentIndex: 0, ac: ac}
}
func TestIteratorTest(t *testing.T) {
arr:=[]interface{}{"a","b","c","d"}
arrayContainer:=&ArrayContainer{arrayData:arr}
iterator:=arrayContainer.GetIterator()
for iterator.HasNext(){
fmt.Println(iterator.Next().(string))
}
}
用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。
已中介者为中心。其他对象的通信都需要连接中介者
type ChatRoom struct {
name string
}
func (cr *ChatRoom)SendMsg(msg string){
fmt.Println(cr.name+" : "+msg)
}
func (cr *ChatRoom)RegisterUser(u *User){
u.cr=cr
}
type User struct {
name string
cr *ChatRoom
}
func (u *User)SendMsg(msg string){
if u.cr!=nil {
u.cr.SendMsg(u.name+" : "+msg)
}
}
func TestMediator(t *testing.T) {
AUser:=&User{name:"AUser"}
BUser:=&User{name:"BUser"}
chatRoom:=&ChatRoom{name:"chatRoom123456"}
chatRoom.RegisterUser(AUser)
chatRoom.RegisterUser(BUser)
AUser.SendMsg("hello AUser")
BUser.SendMsg("hello BUser")
}
保存一个对象的某个状态,以便在适当的时候恢复对象。
所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
// 文本编辑
type Text struct {
Value string
}
// 写
func (t *Text) Write(value string) {
t.Value = value
}
// 读取
func (t *Text) Read() string {
return t.Value
}
// 备忘结构
type Memento struct {
Value string
}
// 备忘
func (t *Text) SaveToMemento() *Memento {
return &Memento{Value: t.Value}
}
// 从备忘恢复
func (t *Text) RestoreFromMemento(m *Memento) {
if m != nil {
t.Value = m.Value
}
return
}
// 管理备忘记录
type Storage struct {
*list.List
}
// Back returns the last element of list l or nil.
// and remove form list
func (s *Storage) RPop() *list.Element {
ele := s.Back()
if ele != nil {
s.Remove(ele)
}
return ele
}
func TestMemento(t *testing.T) {
storage := &Storage{list.New()}
text := &Text{"hello world"}
fmt.Println(text.Read())
storage.PushBack(text.SaveToMemento())
text.Write("nihao")
fmt.Println(text.Read())
storage.PushBack(text.SaveToMemento())
text.Write("i know")
fmt.Println(text.Read())
//后退回滚
mediator := storage.RPop()
if mediator != nil {
text.RestoreFromMemento(mediator.Value.(*Memento))
}
fmt.Println(text.Read())
//后退回滚
mediator = storage.RPop()
if mediator != nil {
text.RestoreFromMemento(mediator.Value.(*Memento))
}
fmt.Println(text.Read())
//后退 已没有
mediator = storage.RPop()
if mediator != nil {
text.RestoreFromMemento(mediator.Value.(*Memento))
}
fmt.Println(text.Read())
}