├── LICENSE ├── README.md └── src ├── adapter ├── adapter-cache-demo │ └── main.go ├── adapter-simple-test.go └── adapter-simple.go ├── bridge └── bridge_pattern.go ├── builder └── code.go ├── chainofresponsibility └── code.go ├── command └── command.go ├── composite └── composite.go ├── decorator └── decorator.go ├── facade └── facade.go ├── factory-template-strategy-bridge └── design.go ├── factory ├── abstract-factory │ └── code.go ├── factory-method │ └── code.go └── simple-factory │ └── demo.go ├── flyweight └── flyweight.go ├── interpreter └── code.go ├── iterator └── iterator.go ├── mediator └── code.go ├── memento └── memento.go ├── observer ├── README.md ├── event_dispatcher.go └── observer.go ├── prototype └── main.go ├── proxy └── proxy.go ├── singleton ├── egger-mode │ └── code.go └── lazy-mode │ └── code.go ├── state └── state.go ├── strategy └── strategy.go ├── template └── template_pattern.go └── visitor └── visitor.go /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Kevin Yan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 用 Go 语言学设计模式 2 | 3 | 4 | ## 建造型模式 5 | - 单例模式 6 | - [教程--最简单的单例模式,Go版本的实现你写对了吗?](https://mp.weixin.qq.com/s/1ZuhUA9Lt2uLFlamIY6fLQ) 7 | - [源码:Go 实现单例模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/singleton) 8 | - 工厂模式 9 | - [教程--用 Go 实现简单工厂、工厂方法、抽象工厂](https://mp.weixin.qq.com/s/MlC6-TDf06LGpF8hxcSV_w) 10 | - [源码:Go 实现工厂模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/factory) 11 | - 原型模式 12 | - [Go学设计模式--原型模式的考查点和使用推荐](https://mp.weixin.qq.com/s/y1qHsQNR7EWeDU5g60Loqg) 13 | - [源码:Go 实现原型模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/prototype) 14 | - 建造者模式 15 | - [教程 -- Go开源库、大项目的公共包,是这么用建造者模式的](https://mp.weixin.qq.com/s/Uu3EAWpRO9pSbg1F1DLa_w) 16 | - [源码:Go实现建造者模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/builder) 17 | 18 | ## 结构型模式 19 | - 代理模式 20 | - [Go学设计模式--怕把核心代码改乱,记得用代理模式](https://mp.weixin.qq.com/s/FTXkgxkUzsHMIspCK60G4w) 21 | - [源码:Go实现代理模式](https://github.com/kevinyan815/design-pattern-by-go/blob/master/src/proxy) 22 | - 装饰器模式 23 | - [教程 -- Go学设计模式--装饰器和职责链,哪个模式实现中间件更科学?](https://mp.weixin.qq.com/s/_e9Qa97gZvgv9n-pFB4lFw) 24 | - [源码:Go实现装饰器模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/decorator) 25 | - 组合模式 26 | - [教程--组合,一个对数据结构算法和职场都有提升的设计模式](https://mp.weixin.qq.com/s/JKWbyr4Yt7A6l1nFsANUcQ) 27 | - [源码:Go实现组合模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/composite) 28 | - 适配器模式 29 | - [教程--项目依赖耦合度太高?可以用适配器做下优化](https://mp.weixin.qq.com/s/r8975amH-DcJkWQKytIeJQ) 30 | - [源码:Go实现适配器模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/adapter) 31 | - 外观模式 32 | - [教程--外观模式,一个每天都在用,却被多数人在面试中忽视的模式](https://mp.weixin.qq.com/s?__biz=MzUzNTY5MzU2MA==&mid=2247497560&idx=1&sn=c3a8f8bc5e8d7748eb16d60a242369f2&chksm=fa8326cfcdf4afd91eab5dab7e556ae134c6b6a059913c3dbde0f7450db9faf8a74e5f1c9834&scene=178&cur_album_id=2531498848431669249#rd) 33 | - [源码:Go实现外观模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/facade) 34 | - 享元模式 35 | - [教程:享元模式,节省内存的好帮手](https://mp.weixin.qq.com/s?__biz=MzUzNTY5MzU2MA==&mid=2247497613&idx=1&sn=428a4ffa977421b2b2c78f36585b7c62&chksm=fa83261acdf4af0c014190c5982b1b5af34018d69e12c3baf5a1f44b680056901103d2afd2c0&scene=178&cur_album_id=2531498848431669249#rd) 36 | - [源码: Go实现享元模式](https://github.com/kevinyan815/design-pattern-by-go/blob/master/src/flyweight) 37 | - 桥接模式 38 | - [教程:桥接模式,让代码既能多维度扩展又不会臃肿](https://mp.weixin.qq.com/s/O8shSU46TcgFPx3h7NGFAA) 39 | - [源码:用桥接模式实现一个数据库导出工具](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/bridge) 40 | 41 | ## 行为型模式 42 | - 观察者模式 43 | - [教程--拒绝Go代码臃肿,其实在这几块可以用下观察者模式](https://mp.weixin.qq.com/s/4NqjkXVqFPamEc_QsyRipA) 44 | - [源码:Go实现观察者模式和事件分发器](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/observer) 45 | - 模版模式 46 | - [教程--提炼流程,减少重复开发就靠它了](https://mp.weixin.qq.com/s/-Ysho1jI9MfrAIrplzj7UQ) 47 | - [源码:Go实现模版模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/template) 48 | - 策略模式 49 | - [Go 程序里 if else 分支太多?试着用策略模式治理一下吧](https://mp.weixin.qq.com/s/IQsojcdwLZ1g0TgVQDoqVw) 50 | - [源码:用Go实现策略模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/strategy) 51 | - 职责链模式 52 | - [教程:程序员上班,提前学会用职责链设计模式预防产品加需求吧](https://mp.weixin.qq.com/s/zCh12E10JM24EGTyFS7hPQ) 53 | - [源码:用Go实现职责链模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/chainofresponsibility) 54 | - 状态模式 55 | - [教程:用状态模式实现系统工作流和状态机](https://mp.weixin.qq.com/s/X9dKNO6sd-OY2VfsZpaElA) 56 | - [源码:用Go实现一个状态机](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/state) 57 | - 迭代器模式 58 | - [教程:Go设计模式-迭代器模式](https://mp.weixin.qq.com/s/sABibBRsC2kknbAH18oatA) 59 | - [源码:用Go实现迭代器模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/iterator) 60 | - 访客模式 61 | - [教程:Go设计模式-访客模式](https://mp.weixin.qq.com/s/qsw89qI8DOXyb4C1XI5QtA) 62 | - [源码:用访客模式实现不同维度的订单统计](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/visitor) 63 | - 备忘录模式 64 | - [教程:Go设计模式-备忘录模式](https://mp.weixin.qq.com/s/RikZAeI2Pic4vYwVNh4HnA) 65 | - [源码:用Go实现备忘录模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/memento) 66 | - 命令模式 67 | - [教程:Go设计模式-命令模式](https://mp.weixin.qq.com/s/n1R1fnRZuDwlaQqsDh5y3g) 68 | - [源码:用Go实现命令模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/command) 69 | - 解释器模式 70 | - [教程:Go设计模式-解释器模式](https://mp.weixin.qq.com/s/8v0UZWygCvkbye4Y0P-3sQ) 71 | - [源码:用Go实现解释器模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/interpreter) 72 | - 中介者模式 73 | - [教程:Go设计模式-中介者模式](https://mp.weixin.qq.com/s/91-XUm5Gn9oQLd_F4dLb3A) 74 | - [源码:用Go实现中介者模式](https://github.com/kevinyan815/design-pattern-by-go/tree/master/src/mediator) 75 | 76 | ## 求支持 77 | 请扫码关注公众号,支持下;也可通过公众号联系到我以及阅读更多精品内容 78 | image 79 | -------------------------------------------------------------------------------- /src/adapter/adapter-cache-demo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/gomodule/redigo/redis" 8 | ) 9 | 10 | // Cache is the adapter contract between the application and the cache library. 11 | type Cache interface { 12 | Put(key string, value interface{}) 13 | PutAll(map[string]interface{}) 14 | Get(key string) interface{} 15 | GetAll(keys []string) map[string]interface{} 16 | Clean(key string) 17 | CleanAll() 18 | } 19 | 20 | // RedisCache holds a Redis connection pool. 21 | type RedisCache struct { 22 | conn *redis.Pool 23 | } 24 | 25 | // Put adds an entry in the cache. 26 | func (rc *RedisCache) Put(key string, value interface{}) { 27 | if _, err := rc.conn.Get().Do("SET", key, value); err != nil { 28 | fmt.Println(err) 29 | } 30 | } 31 | 32 | // PutAll adds the entries of a map in the cache. 33 | func (rc *RedisCache) PutAll(entries map[string]interface{}) { 34 | c := rc.conn.Get() 35 | for k, v := range entries { 36 | if err := c.Send("SET", k, v); err != nil { 37 | fmt.Println(err) 38 | } 39 | } 40 | 41 | if err := c.Flush(); err != nil { 42 | fmt.Println(err) 43 | } 44 | } 45 | 46 | // Get gets an entry from the cache. 47 | func (rc *RedisCache) Get(key string) interface{} { 48 | value, err := redis.String(rc.conn.Get().Do("GET", key)) 49 | if err != nil { 50 | fmt.Println(err) 51 | return "" 52 | } 53 | return value 54 | } 55 | 56 | // GetAll gets all the entries of a map from the cache. 57 | func (rc *RedisCache) GetAll(keys []string) map[string]interface{} { 58 | // Converts []string to []interface{} since Go doesn't do it explicitly 59 | // because it doesn't want the syntax to hide a O(n) operation. 60 | intKeys := make([]interface{}, len(keys)) 61 | for i, _ := range keys { 62 | intKeys[i] = keys[i] 63 | } 64 | 65 | c := rc.conn.Get() 66 | entries := make(map[string]interface{}) 67 | values, err := redis.Strings(c.Do("MGET", intKeys...)) 68 | if err != nil { 69 | fmt.Println(err) 70 | return entries 71 | } 72 | 73 | for i, k := range keys { 74 | entries[k] = values[i] 75 | } 76 | 77 | return entries 78 | } 79 | 80 | // Clean cleans a entry from the cache. 81 | func (rc *RedisCache) Clean(key string) { 82 | if _, err := rc.conn.Get().Do("DEL", key); err != nil { 83 | fmt.Println(err) 84 | } 85 | } 86 | 87 | // CleanAll cleans the entire cache. 88 | func (rc *RedisCache) CleanAll() { 89 | if _, err := rc.conn.Get().Do("FLUSHDB"); err != nil { 90 | fmt.Println(err) 91 | } 92 | } 93 | 94 | // GetCachingMechanism initializes and returns a caching mechanism. 95 | func NewRedisCache() Cache { 96 | cache := &RedisCache{ 97 | conn: &redis.Pool{ 98 | MaxIdle: 7, 99 | MaxActive: 30, 100 | IdleTimeout: 60 * time.Second, 101 | Dial: func() (redis.Conn, error) { 102 | conn, err := redis.Dial("tcp", "localhost:6379") 103 | if err != nil { 104 | fmt.Println(err) 105 | return nil, err 106 | } 107 | 108 | if _, err := conn.Do("SELECT", 0); err != nil { 109 | conn.Close() 110 | fmt.Println(err) 111 | return nil, err 112 | } 113 | 114 | return conn, nil 115 | }, 116 | }, 117 | } 118 | return cache 119 | } 120 | 121 | func main() { 122 | rc := NewRedisCache() 123 | rc.Put("网管叨逼叨", "rub fish") 124 | } 125 | -------------------------------------------------------------------------------- /src/adapter/adapter-simple-test.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | import "testing" 4 | 5 | var expect = "adaptee method" 6 | 7 | func TestAdapter(t *testing.T) { 8 | adaptee := NewAdaptee() 9 | target := NewAdapter(adaptee) 10 | res := target.Request() 11 | if res != expect { 12 | t.Fatalf("expect: %s, actual: %s", expect, res) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/adapter/adapter-simple.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | //Target 适配器接口,描述客户端和被适配服务间约定的接口 4 | type Target interface { 5 | Request() string 6 | } 7 | 8 | //Adaptee 是被适配的目标接口 9 | type Adaptee interface { 10 | SpecificRequest() string 11 | } 12 | 13 | //NewAdaptee 是被适配接口的工厂函数 14 | func NewAdaptee() Adaptee { 15 | return &adapteeImpl{} 16 | } 17 | 18 | //AdapteeImpl 是被适配的目标类 19 | type adapteeImpl struct{} 20 | 21 | //SpecificRequest 是目标类的一个方法 22 | func (*adapteeImpl) SpecificRequest() string { 23 | return "adaptee method" 24 | } 25 | 26 | //NewAdapter 是Adapter的工厂函数 27 | func NewAdapter(adaptee Adaptee) Target { 28 | return &adapter{ 29 | Adaptee: adaptee, 30 | } 31 | } 32 | 33 | //Adapter 是转换Adaptee为Target接口的适配器 34 | type adapter struct { 35 | Adaptee 36 | } 37 | 38 | //Request 实现Target接口 39 | func (a *adapter) Request() string { 40 | return a.SpecificRequest() 41 | } 42 | -------------------------------------------------------------------------------- /src/bridge/bridge_pattern.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "math/rand" 8 | ) 9 | 10 | // 数据导出器 11 | type IDataExporter interface { 12 | Fetcher(fetcher IDataFetcher) 13 | Export(sql string, writer io.Writer) error 14 | } 15 | 16 | // 数据查询器 17 | type IDataFetcher interface { 18 | Fetch(sql string) []interface{} 19 | } 20 | 21 | type MysqlDataFetcher struct { 22 | Config string 23 | } 24 | 25 | func (mf *MysqlDataFetcher) Fetch(sql string) []interface{} { 26 | fmt.Println("Fetch data from mysql source: " + mf.Config) 27 | rows := make([]interface{}, 0) 28 | rows = append(rows, rand.Perm(10), rand.Perm(10)) 29 | return rows 30 | } 31 | 32 | func NewMysqlDataFetcher(configStr string) IDataFetcher { 33 | return &MysqlDataFetcher{ 34 | Config: configStr, 35 | } 36 | } 37 | 38 | type OracleDataFetcher struct { 39 | Config string 40 | } 41 | 42 | func NewOracleDataFetcher(configStr string) IDataFetcher { 43 | return &OracleDataFetcher{ 44 | configStr, 45 | } 46 | } 47 | 48 | func (of *OracleDataFetcher) Fetch(sql string) []interface{} { 49 | fmt.Println("Fetch data from oracle source: " + of.Config) 50 | rows := make([]interface{}, 0) 51 | rows = append(rows, rand.Perm(10), rand.Perm(10)) 52 | return rows 53 | } 54 | 55 | 56 | 57 | type CsvExporter struct { 58 | mFetcher IDataFetcher 59 | } 60 | 61 | func NewCsvExporter(fetcher IDataFetcher) IDataExporter { 62 | return &CsvExporter{ 63 | fetcher, 64 | } 65 | } 66 | 67 | func (ce *CsvExporter) Fetcher(fetcher IDataFetcher) { 68 | ce.mFetcher = fetcher 69 | } 70 | 71 | func (ce *CsvExporter) Export(sql string, writer io.Writer) error { 72 | rows := ce.mFetcher.Fetch(sql) 73 | fmt.Printf("CsvExporter.Export, got %v rows\n", len(rows)) 74 | for i, v:= range rows { 75 | fmt.Printf(" 行号: %d 值: %s\n", i + 1, v) 76 | } 77 | return nil 78 | } 79 | 80 | type JsonExporter struct { 81 | mFetcher IDataFetcher 82 | } 83 | 84 | func NewJsonExporter(fetcher IDataFetcher) IDataExporter { 85 | return &JsonExporter{ 86 | fetcher, 87 | } 88 | } 89 | 90 | func (je *JsonExporter) Fetcher(fetcher IDataFetcher) { 91 | je.mFetcher = fetcher 92 | } 93 | 94 | func (je *JsonExporter) Export(sql string, writer io.Writer) error { 95 | rows := je.mFetcher.Fetch(sql) 96 | fmt.Printf("JsonExporter.Export, got %v rows\n", len(rows)) 97 | for i, v:= range rows { 98 | fmt.Printf(" 行号: %d 值: %s\n", i + 1, v) 99 | } 100 | return nil 101 | } 102 | 103 | 104 | func main() { 105 | mFetcher := NewMysqlDataFetcher("mysql://127.0.0.1:3306") 106 | csvExporter := NewCsvExporter(mFetcher) 107 | var writer bytes.Buffer 108 | // 从MySQL数据源导出 CSV 109 | csvExporter.Export("select * from xxx", &writer) 110 | 111 | oFetcher := NewOracleDataFetcher("mysql://127.0.0.1:1001") 112 | csvExporter.Fetcher(oFetcher) 113 | // 从 Oracle 数据源导出 CSV 114 | csvExporter.Export("select * from xxx", &writer) 115 | 116 | // 从 MySQL 数据源导出 JSON 117 | jsonExporter := NewJsonExporter(mFetcher) 118 | jsonExporter.Export("select * from xxx", &writer) 119 | } 120 | -------------------------------------------------------------------------------- /src/builder/code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | type DBPool struct { 9 | dsn string 10 | maxOpenConn int 11 | maxIdleConn int 12 | maxConnLifeTime time.Duration 13 | } 14 | 15 | type DBPoolBuilder struct { 16 | DBPool 17 | err error 18 | } 19 | 20 | func Builder () *DBPoolBuilder { 21 | b := new(DBPoolBuilder) 22 | // 设置 DBPool 属性的默认值 23 | b.DBPool.dsn = "127.0.0.1:3306" 24 | b.DBPool.maxConnLifeTime = 1 * time.Second 25 | b.DBPool.maxOpenConn = 30 26 | return b 27 | } 28 | 29 | func (b *DBPoolBuilder) DSN(dsn string) *DBPoolBuilder { 30 | if b.err != nil { 31 | return b 32 | } 33 | if dsn == "" { 34 | b.err = fmt.Errorf("invalid dsn, current is %s", dsn) 35 | } 36 | 37 | b.DBPool.dsn = dsn 38 | return b 39 | } 40 | 41 | func (b *DBPoolBuilder) MaxOpenConn(connNum int) *DBPoolBuilder { 42 | if b.err != nil { 43 | return b 44 | } 45 | if connNum < 1 { 46 | b.err = fmt.Errorf("invalid MaxOpenConn, current is %d", connNum) 47 | } 48 | 49 | b.DBPool.maxOpenConn = connNum 50 | return b 51 | } 52 | 53 | func (b *DBPoolBuilder) MaxConnLifeTime(lifeTime time.Duration) *DBPoolBuilder { 54 | if b.err != nil { 55 | return b 56 | } 57 | if lifeTime < 1 * time.Second { 58 | b.err = fmt.Errorf("connection max life time can not litte than 1 second, current is %v", lifeTime) 59 | } 60 | 61 | b.DBPool.maxConnLifeTime = lifeTime 62 | return b 63 | } 64 | 65 | func (b *DBPoolBuilder) Build() (*DBPool, error) { 66 | if b.err != nil { 67 | return nil, b.err 68 | } 69 | if b.DBPool.maxOpenConn < b.DBPool.maxIdleConn { 70 | return nil, fmt.Errorf("max total(%d) cannot < max idle(%d)", b.DBPool.maxOpenConn, b.DBPool.maxIdleConn) 71 | } 72 | return &b.DBPool, nil 73 | } 74 | 75 | func main() { 76 | dbPool, err := Builder().DSN("localhost:3306").MaxOpenConn(50).MaxConnLifeTime(10 * time.Second).Build() 77 | if err != nil { 78 | fmt.Println(err) 79 | } 80 | fmt.Println(dbPool) 81 | } 82 | -------------------------------------------------------------------------------- /src/chainofresponsibility/code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type PatientHandler interface { 6 | Execute(*patient) error 7 | SetNext(PatientHandler) PatientHandler 8 | Do(*patient) error 9 | } 10 | 11 | type Next struct { 12 | nextHandler PatientHandler 13 | } 14 | 15 | func (n *Next) SetNext(handler PatientHandler) PatientHandler { 16 | n.nextHandler = handler 17 | return handler 18 | } 19 | 20 | func (n *Next) Execute(patient *patient) (err error) { 21 | // 由于go无继承的概念, 只能用组合,组合跟继承不一样,这里如果Next 实现了 Do 方法,那么匿名组合它的具体处理类型,执行Execute的时候,调用的还是内部Next对象的Do方法 22 | // 调用不到外部类型的 Do 方法,所以 Next 不能实现 Do 方法 23 | if n.nextHandler != nil { 24 | if err = n.nextHandler.Do(patient); err != nil { 25 | return 26 | } 27 | 28 | return n.nextHandler.Execute(patient) 29 | } 30 | 31 | return 32 | } 33 | 34 | // Pharmacy 药房处理器 35 | type Pharmacy struct { 36 | Next 37 | } 38 | 39 | 40 | func (m *Pharmacy) Do (p *patient) (err error) { 41 | if p.MedicineDone { 42 | fmt.Println("Medicine already given to patient") 43 | return 44 | } 45 | fmt.Println("Pharmacy giving medicine to patient") 46 | p.MedicineDone = true 47 | return 48 | } 49 | 50 | // Cashier 收费处处理器 51 | type Cashier struct { 52 | Next 53 | } 54 | 55 | func (c *Cashier) Do(p *patient) (err error) { 56 | if p.PaymentDone { 57 | fmt.Println("Payment Done") 58 | return 59 | } 60 | fmt.Println("Cashier getting money from patient patient") 61 | p.PaymentDone = true 62 | return 63 | } 64 | 65 | // Clinic 诊室处理器--用于医生给病人看病 66 | type Clinic struct { 67 | Next 68 | } 69 | 70 | func (d *Clinic) Do(p *patient) (err error) { 71 | if p.DoctorCheckUpDone { 72 | fmt.Println("Doctor checkup already done") 73 | return 74 | } 75 | fmt.Println("Doctor checking patient") 76 | p.DoctorCheckUpDone = true 77 | return 78 | } 79 | 80 | // Reception 挂号处处理器 81 | type Reception struct { 82 | Next 83 | } 84 | 85 | func (r *Reception) Do(p *patient) (err error) { 86 | if p.RegistrationDone { 87 | fmt.Println("Patient registration already done") 88 | return 89 | } 90 | fmt.Println("Reception registering patient") 91 | p.RegistrationDone = true 92 | return 93 | } 94 | 95 | // StartHandler 不做操作,作为第一个Handler向下转发请求 96 | // Go 语法限制,抽象公共逻辑到通用Handler后,并不能跟继承一样让公共方法调用不通子类的实现 97 | type StartHandler struct { 98 | Next 99 | } 100 | 101 | // Do 空Handler的Do 102 | func (h *StartHandler) Do(c *patient) (err error) { 103 | // 空Handler 这里什么也不做 只是载体 do nothing... 104 | return 105 | } 106 | 107 | type patient struct { 108 | Name string 109 | RegistrationDone bool 110 | DoctorCheckUpDone bool 111 | MedicineDone bool 112 | PaymentDone bool 113 | } 114 | func main() { 115 | patientHealthHandler := StartHandler{} 116 | // 117 | patient := &patient{Name: "abc"} 118 | // 设置病人看病的链路 119 | patientHealthHandler.SetNext(&Reception{}).// 挂号 120 | SetNext(&Clinic{}). // 诊室看病 121 | SetNext(&Cashier{}). // 收费处交钱 122 | SetNext(&Pharmacy{}) // 药房拿药 123 | // 还可以无效扩展,比如中间加入化验科化验,图像科拍片等等 124 | 125 | // 执行上面设置好的业务流程 126 | if err := patientHealthHandler.Execute(patient); err != nil { 127 | // 异常 128 | fmt.Println("Fail | Error:" + err.Error()) 129 | return 130 | } 131 | // 成功 132 | fmt.Println("Success") 133 | } 134 | -------------------------------------------------------------------------------- /src/command/command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 命令接收者,负责逻辑的执行 6 | type CPU struct{} 7 | 8 | func (CPU) ADoSomething(param int) { 9 | fmt.Printf("a do something with param %v\n", param) 10 | } 11 | func (CPU) BDoSomething(param1 string, param2 int) { 12 | fmt.Printf("b do something with params %v and %v \n", param1, param2) 13 | } 14 | func (CPU) CDoSomething() { 15 | fmt.Println("c do something with no params") 16 | } 17 | 18 | // 接口中仅声明一个执行命令的方法 Execute() 19 | type Command interface { 20 | Execute() 21 | } 22 | 23 | // 命令对象持有一个指向接收者的引用,以及请求中的所有参数, 24 | type ACommand struct { 25 | cpu *CPU 26 | param int 27 | } 28 | // 命令不会进行逻辑处理,调用Execute方法会将发送者的请求委派给接收者对象。 29 | func (a ACommand) Execute() { 30 | a.cpu.ADoSomething(a.param) 31 | a.cpu.CDoSomething()// 可以执行多个接收者的操作完成命令宏 32 | } 33 | 34 | func NewACommand(cpu *CPU, param int) Command { 35 | return ACommand{cpu, param} 36 | } 37 | 38 | type BCommand struct { 39 | state bool // Command 里可以添加些状态用作逻辑判断 40 | cpu *CPU 41 | param1 string 42 | param2 int 43 | } 44 | 45 | func (b BCommand) Execute() { 46 | if b.state { 47 | return 48 | } 49 | b.cpu.BDoSomething(b.param1, b.param2) 50 | b.state = true 51 | b.cpu.CDoSomething() 52 | } 53 | 54 | func NewBCommand(cpu *CPU, param1 string, param2 int) Command { 55 | return BCommand{false,cpu, param1, param2} 56 | } 57 | 58 | type PS5 struct { 59 | commands map[string]Command 60 | } 61 | 62 | // SetCommand方法来将 Command 指令设定给PS5。 63 | func (p *PS5) SetCommand(name string, command Command) { 64 | p.commands[name] = command 65 | } 66 | // DoCommand方法选择要执行的命令 67 | func (p *PS5) DoCommand(name string) { 68 | p.commands[name].Execute() 69 | } 70 | 71 | func main() { 72 | cpu := CPU{} 73 | // main方法充当客户端,创建并配置具体命令对象, 完成命令与执行操作的接收者的关联。 74 | ps5 := PS5{make(map[string]Command)} 75 | ps5.SetCommand("a", NewACommand(&cpu, 1)) 76 | ps5.SetCommand("b", NewBCommand(&cpu, "hello", 2)) 77 | ps5.DoCommand("a") 78 | ps5.DoCommand("b") 79 | } 80 | -------------------------------------------------------------------------------- /src/composite/composite.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // 表示组织机构的接口 9 | type Organization interface { 10 | display() 11 | duty() 12 | } 13 | 14 | // 组合对象--上级部门 15 | type CompositeOrganization struct { 16 | orgName string 17 | depth int 18 | list []Organization 19 | } 20 | 21 | func NewCompositeOrganization(name string, depth int) *CompositeOrganization { 22 | return &CompositeOrganization{name, depth, []Organization{}} 23 | } 24 | 25 | func (c *CompositeOrganization) add(org Organization) { 26 | if c == nil { 27 | return 28 | } 29 | c.list = append(c.list, org) 30 | } 31 | 32 | func (c *CompositeOrganization) remove(org Organization) { 33 | if c == nil { 34 | return 35 | } 36 | for i, val := range c.list { 37 | if val == org { 38 | c.list = append(c.list[:i], c.list[i+1:]...) 39 | return 40 | } 41 | } 42 | return 43 | } 44 | 45 | func (c *CompositeOrganization) display() { 46 | if c == nil { 47 | return 48 | } 49 | fmt.Println(strings.Repeat("-", c.depth * 2), " ", c.orgName) 50 | for _, val := range c.list { 51 | val.display() 52 | } 53 | } 54 | 55 | func (c *CompositeOrganization) duty() { 56 | if c == nil { 57 | return 58 | } 59 | 60 | for _, val := range c.list { 61 | val.duty() 62 | } 63 | } 64 | 65 | // Leaf对象--人力资源部门 66 | type HRDOrg struct { 67 | orgName string 68 | depth int 69 | } 70 | 71 | func (o *HRDOrg) display() { 72 | if o == nil { 73 | return 74 | } 75 | fmt.Println(strings.Repeat("-", o.depth * 2), " ", o.orgName) 76 | } 77 | 78 | func (o *HRDOrg) duty() { 79 | if o == nil { 80 | return 81 | } 82 | fmt.Println(o.orgName, "员工招聘培训管理") 83 | } 84 | 85 | // Leaf对象--财务部门 86 | type FinanceOrg struct { 87 | orgName string 88 | depth int 89 | } 90 | 91 | func (f *FinanceOrg) display() { 92 | if f == nil { 93 | return 94 | } 95 | fmt.Println(strings.Repeat("-", f.depth * 2), " ", f.orgName) 96 | } 97 | 98 | func (f *FinanceOrg) duty() { 99 | if f == nil { 100 | return 101 | } 102 | fmt.Println(f.orgName, "员工招聘培训管理") 103 | } 104 | 105 | func main() { 106 | root := NewCompositeOrganization("北京总公司", 1) 107 | root.add(&HRDOrg{orgName: "总公司人力资源部", depth: 2}) 108 | root.add(&FinanceOrg{orgName: "总公司财务部", depth: 2}) 109 | 110 | compSh := NewCompositeOrganization("上海分公司", 2) 111 | compSh.add(&HRDOrg{orgName: "上海分公司人力资源部", depth: 3}) 112 | compSh.add(&FinanceOrg{orgName: "上海分公司财务部", depth: 3}) 113 | root.add(compSh) 114 | 115 | compGd := NewCompositeOrganization("广东分公司", 2) 116 | compGd.add(&HRDOrg{orgName: "广东分公司人力资源部", depth: 3}) 117 | compGd.add(&FinanceOrg{orgName: "南京办事处财务部", depth: 3}) 118 | root.add(compGd) 119 | 120 | fmt.Println("公司组织架构:") 121 | root.display() 122 | 123 | fmt.Println("各组织的职责:") 124 | root.duty() 125 | } 126 | -------------------------------------------------------------------------------- /src/decorator/decorator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // PS5 产品接口 6 | type PS5 interface { 7 | StartGPUEngine() 8 | GetPrice() int64 9 | } 10 | 11 | // CD 版 PS5主机 12 | type PS5WithCD struct{} 13 | 14 | func (p PS5WithCD) StartGPUEngine() { 15 | fmt.Println("start engine") 16 | } 17 | func (p PS5WithCD) GetPrice() int64 { 18 | return 5000 19 | } 20 | 21 | // PS5 数字版主机 22 | type PS5WithDigital struct{} 23 | 24 | func (p PS5WithDigital) StartGPUEngine() { 25 | fmt.Println("start normal gpu engine") 26 | } 27 | 28 | func (p PS5WithDigital) GetPrice() int64 { 29 | return 3600 30 | } 31 | 32 | type PS5MachinePlus struct { 33 | ps5Machine PS5 34 | } 35 | 36 | func (p *PS5MachinePlus) SetPS5Machine(ps5 PS5) { 37 | p.ps5Machine = ps5 38 | } 39 | 40 | func (p PS5MachinePlus) StartGPUEngine() { 41 | p.ps5Machine.StartGPUEngine() 42 | fmt.Println("start plus plugin") 43 | } 44 | 45 | func (p PS5MachinePlus) GetPrice() int64 { 46 | return p.ps5Machine.GetPrice() + 500 47 | } 48 | 49 | // 主题色版 PS5 主机 50 | type PS5WithTopicColor struct { 51 | ps5Machine PS5 52 | } 53 | 54 | func (p *PS5WithTopicColor) SetPS5Machine(ps5 PS5) { 55 | p.ps5Machine = ps5 56 | } 57 | 58 | func (p PS5WithTopicColor) StartGPUEngine() { 59 | p.ps5Machine.StartGPUEngine() 60 | fmt.Println("尊贵的主题色主机,GPU启动") 61 | } 62 | func (p PS5WithTopicColor) GetPrice() int64 { 63 | return p.ps5Machine.GetPrice() + 200 64 | } 65 | 66 | func main() { 67 | ps5MachinePlus := PS5MachinePlus{} 68 | ps5MachinePlus.SetPS5Machine(PS5WithCD{}) 69 | // ps5MachinePlus.SetPS5Machine(PS5WithDigital{}) // 可以在更换主机 70 | ps5MachinePlus.StartGPUEngine() 71 | price := ps5MachinePlus.GetPrice() 72 | fmt.Printf("PS5 CD 豪华Plus版,价格: %d 元\n\n", price) 73 | 74 | ps5WithTopicColor := PS5WithTopicColor{} 75 | ps5WithTopicColor.SetPS5Machine(ps5MachinePlus) 76 | ps5WithTopicColor.StartGPUEngine() 77 | price = ps5WithTopicColor.GetPrice() 78 | fmt.Printf("PS5 CD 豪华Plus 经典主题配色版,价格: %d 元\n", price) 79 | } 80 | -------------------------------------------------------------------------------- /src/facade/facade.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const ( 8 | BOOT_ADDRESS = 0 9 | BOOT_SECTOR = 0 10 | SECTOR_SIZE = 0 11 | ) 12 | 13 | type CPU struct{} 14 | 15 | func (c *CPU) Freeze() { 16 | fmt.Println("CPU.Freeze()") 17 | } 18 | 19 | func (c *CPU) Jump(position int) { 20 | fmt.Println("CPU.Jump()") 21 | } 22 | 23 | func (c *CPU) Execute() { 24 | fmt.Println("CPU.Execute()") 25 | } 26 | 27 | type Memory struct{} 28 | 29 | func (m *Memory) Load(position int, data []byte) { 30 | fmt.Println("Memory.Load()") 31 | } 32 | 33 | type HardDrive struct{} 34 | 35 | func (hd *HardDrive) Read(lba int, size int) []byte { 36 | fmt.Println("HardDrive.Read()") 37 | return make([]byte, 0) 38 | } 39 | 40 | type ComputerFacade struct { 41 | processor *CPU 42 | ram *Memory 43 | hd *HardDrive 44 | } 45 | 46 | func NewComputerFacade() *ComputerFacade { 47 | return &ComputerFacade{new(CPU), new(Memory), new(HardDrive)} 48 | } 49 | 50 | func (c *ComputerFacade) start() { 51 | c.processor.Freeze() 52 | c.ram.Load(BOOT_ADDRESS, c.hd.Read(BOOT_SECTOR, SECTOR_SIZE)) 53 | c.processor.Jump(BOOT_ADDRESS) 54 | c.processor.Execute() 55 | } 56 | 57 | func main() { 58 | computer := NewComputerFacade() 59 | computer.start() 60 | } 61 | -------------------------------------------------------------------------------- /src/factory-template-strategy-bridge/design.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | type InsureTemplateI interface { 9 | ExecuteInsure() (*Response, error) 10 | InsureHandlerI 11 | } 12 | 13 | type InsureHandlerI interface { 14 | ValidateRequest() error 15 | 16 | CheckRepetition() error 17 | // FillInClientRequest decrypt specific data into request's specific field 18 | FillInClientRequest() error 19 | // PrepareOrderCreateParam Prepare and get basic data for order creation 20 | PrepareOrderCreateParam() error 21 | LoadInsurePayStrategy() error 22 | // HandleInsure Handle the process of create order 23 | HandleInsure() (*Response, error) 24 | } 25 | 26 | 27 | type InsurePayStrategyI interface { 28 | 29 | DoPayCreateLogic(*OrderCreateParam, *InsuringStore) error 30 | 31 | GetInsureCreateResponse() *Response 32 | } 33 | 34 | 35 | // InsureTemplate working as an abstract class 36 | // it only implements the template method `ExecuteInsure` 37 | // In this `ExecuteInsure` method we will define the exact 38 | // steps for this insure business. 39 | type InsureTemplate struct { 40 | InsureHandlerI 41 | } 42 | 43 | func (template InsureTemplate) ExecuteInsure() (*Response, error) { 44 | fmt.Println("ValidateRequest") 45 | err := template.ValidateRequest() 46 | if err != nil { 47 | return nil, err 48 | } 49 | err = template.CheckRepetition() 50 | if err != nil { 51 | return nil, err 52 | } 53 | err = template.PrepareOrderCreateParam() 54 | if err != nil { 55 | return nil, err 56 | } 57 | fmt.Println("LoadInsurePayStrategy") 58 | err = template.LoadInsurePayStrategy() 59 | if err != nil { 60 | return nil, err 61 | } 62 | response, err := template.HandleInsure() 63 | if err != nil { 64 | return nil, err 65 | } 66 | 67 | return response, nil 68 | } 69 | 70 | // ------------- InsureTemplate ends ------------- // 71 | 72 | 73 | 74 | // GeneralInsureHandler working as a base class for all insure handler, 75 | // and it implements the common implementation for handle insure. 76 | // If other more specific handler have their own logic to implement these methods 77 | // then over right them. 78 | // Since go is incapable of having hierarchy like oop language, 79 | // so we use composition that compose this `GeneralInsureHandler` into specific handler 80 | // to overwrite the common version of InsureHandlerI's methods. 81 | type GeneralInsureHandler struct { 82 | // pay strategy 83 | Strategy InsurePayStrategyI 84 | //originalReqByte []byte 85 | 86 | // necessary data for creating data 87 | InsureCreateOrderReq *OrderCreateParam 88 | // client request 89 | ClientInsureReq *Request 90 | InsuringStore *InsuringStore 91 | } 92 | 93 | func (handler *GeneralInsureHandler) ValidateRequest() error { 94 | fmt.Println("in ValidateRequest") 95 | if handler.ClientInsureReq.FieldA == "" { 96 | return errors.New("lack of filed A") 97 | } 98 | return nil 99 | } 100 | 101 | func (handler *GeneralInsureHandler) CheckRepetition() error { 102 | if handler.ClientInsureReq.FieldB == "" { 103 | return errors.New("repetition happened") 104 | } 105 | return nil 106 | } 107 | 108 | func (handler *GeneralInsureHandler) FillInClientRequest() error { 109 | return nil 110 | } 111 | 112 | func (handler *GeneralInsureHandler) PrepareOrderCreateParam() error { 113 | handler.InsureCreateOrderReq = nil 114 | return nil 115 | } 116 | 117 | func (handler *GeneralInsureHandler) LoadInsurePayStrategy() error { 118 | fmt.Println("in LoadInsurePayStrategy") 119 | //handler.Strategy = new(strategy.InsureStrategyA) 120 | return nil 121 | } 122 | 123 | func (handler *GeneralInsureHandler) HandleInsure() (*Response, error) { 124 | err := handler.Strategy.DoPayCreateLogic(handler.InsureCreateOrderReq, handler.InsuringStore) 125 | if err != nil { 126 | return nil, err 127 | } 128 | reply := handler.Strategy.GetInsureCreateResponse() 129 | 130 | fmt.Println("HandleInsure success end") 131 | return reply, nil 132 | } 133 | 134 | // ------------- GeneralInsureHandler ends ------------- // 135 | 136 | 137 | // SpecificInsureHandler represents concretes for InsureHandlerI 138 | // that actual logics were written into. 139 | type SpecificInsureHandler struct { 140 | GeneralInsureHandler 141 | } 142 | 143 | func (handler *SpecificInsureHandler) FillInClientRequest() error { 144 | return nil 145 | } 146 | 147 | func (handler *SpecificInsureHandler) LoadInsurePayStrategy() error { 148 | 149 | fmt.Println("Load strategy in SpecificInsureHandler") 150 | if handler.ClientInsureReq.FieldA == "a" { 151 | handler.Strategy = new(InsureStrategyA) 152 | return nil 153 | } 154 | 155 | return errors.New("load strategy failed") 156 | } 157 | 158 | // ------------- SpecificInsureHandler ends ------------- // 159 | 160 | 161 | 162 | type InsureStrategyA struct { 163 | reply *Response 164 | } 165 | 166 | func (a *InsureStrategyA) DoPayCreateLogic(param *OrderCreateParam, insuringStore *InsuringStore) error { 167 | return nil 168 | } 169 | 170 | func (a *InsureStrategyA) GetInsureCreateResponse() *Response { 171 | // In this method we can intercept the reply and some customize data 172 | // based on the strategy's logic (If it does have the needs to customize them) 173 | // otherwise we will simply return the reply 174 | return a.reply 175 | } 176 | 177 | 178 | 179 | // Response represent the response of request execution 180 | type Response struct { 181 | 182 | } 183 | 184 | type Request struct { 185 | FieldA string 186 | FieldB string 187 | } 188 | 189 | type OrderCreateParam struct { 190 | 191 | } 192 | 193 | // InsuringStore store data generated that inside business login 194 | type InsuringStore struct { 195 | 196 | } 197 | 198 | // NewInsureTemplate a simple factory for manufacturing insure template 199 | func NewInsureTemplate(clientRequest *Request, symbol string) *InsureTemplate { 200 | insureTemplate := new(InsureTemplate) 201 | switch symbol { 202 | case "a": 203 | insureHandler := new(SpecificInsureHandler) 204 | insureHandler.ClientInsureReq = clientRequest 205 | insureTemplate.InsureHandlerI = insureHandler 206 | 207 | } 208 | 209 | return insureTemplate 210 | } 211 | 212 | func main() { 213 | reqeust := &Request{ 214 | FieldA: "a", 215 | FieldB: "b", 216 | } 217 | template := NewInsureTemplate(reqeust, "a") 218 | fmt.Println("start") 219 | template.ExecuteInsure() 220 | } 221 | -------------------------------------------------------------------------------- /src/factory/abstract-factory/code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 示例源码运行Demo 6 | // 给公众号「网管叨bi叨」发生 go-factory 即可领取 7 | type AbstractFactory interface { 8 | CreateTelevision() ITelevision 9 | CreateAirConditioner() IAirConditioner 10 | } 11 | 12 | type ITelevision interface { 13 | Watch() 14 | } 15 | 16 | type IAirConditioner interface { 17 | SetTemperature(int) 18 | } 19 | 20 | type HuaWeiFactory struct{} 21 | 22 | func (hf *HuaWeiFactory) CreateTelevision() ITelevision { 23 | return &HuaWeiTV{} 24 | } 25 | func (hf *HuaWeiFactory) CreateAirConditioner() IAirConditioner { 26 | return &HuaWeiAirConditioner{} 27 | } 28 | 29 | type HuaWeiTV struct{} 30 | 31 | func (ht *HuaWeiTV) Watch() { 32 | fmt.Println("Watch HuaWei TV") 33 | } 34 | 35 | type HuaWeiAirConditioner struct{} 36 | 37 | func (ha *HuaWeiAirConditioner) SetTemperature(temp int) { 38 | fmt.Printf("HuaWei AirConditioner set temperature to %d ℃\n", temp) 39 | } 40 | 41 | type MiFactory struct{} 42 | 43 | func (mf *MiFactory) CreateTelevision() ITelevision { 44 | return &MiTV{} 45 | } 46 | func (mf *MiFactory) CreateAirConditioner() IAirConditioner { 47 | return &MiAirConditioner{} 48 | } 49 | 50 | type MiTV struct{} 51 | 52 | func (mt *MiTV) Watch() { 53 | fmt.Println("Watch HuaWei TV") 54 | } 55 | 56 | type MiAirConditioner struct{} 57 | 58 | func (ma *MiAirConditioner) SetTemperature(temp int) { 59 | fmt.Printf("Mi AirConditioner set temperature to %d ℃\n", temp) 60 | } 61 | 62 | 63 | func main() { 64 | var factory AbstractFactory 65 | var tv ITelevision 66 | var air IAirConditioner 67 | 68 | factory = &HuaWeiFactory{} 69 | tv = factory.CreateTelevision() 70 | air = factory.CreateAirConditioner() 71 | tv.Watch() 72 | air.SetTemperature(25) 73 | 74 | factory = &MiFactory{} 75 | tv = factory.CreateTelevision() 76 | air = factory.CreateAirConditioner() 77 | tv.Watch() 78 | air.SetTemperature(26) 79 | } 80 | -------------------------------------------------------------------------------- /src/factory/factory-method/code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // MathOperator 实际产品实现的接口--表示数学运算器应该有哪些行为 6 | type MathOperator interface { 7 | SetOperandA(int) 8 | SetOperandB(int) 9 | ComputeResult() int 10 | } 11 | 12 | // OperatorFactory 工厂接口,由具体工厂类来实现 13 | type OperatorFactory interface { 14 | Create() MathOperator 15 | } 16 | 17 | // BaseOperator 是所有 Operator 的基类 18 | // 封装公用方法,因为Go不支持继承,具体Operator类 19 | // 只能组合它来实现类似继承的行为表现。 20 | type BaseOperator struct { 21 | operandA, operandB int 22 | } 23 | 24 | func (o *BaseOperator) SetOperandA(operand int) { 25 | o.operandA = operand 26 | } 27 | 28 | func (o *BaseOperator) SetOperandB(operand int) { 29 | o.operandB = operand 30 | } 31 | 32 | //PlusOperatorFactory 是 PlusOperator 加法运算器的工厂类 33 | type PlusOperatorFactory struct{} 34 | 35 | func (pf *PlusOperatorFactory) Create() MathOperator { 36 | return &PlusOperator{ 37 | BaseOperator: &BaseOperator{}, 38 | } 39 | } 40 | 41 | //PlusOperator 实际的产品类--加法运算器 42 | type PlusOperator struct { 43 | *BaseOperator 44 | } 45 | 46 | //ComputeResult 计算并获取结果 47 | func (p *PlusOperator) ComputeResult() int { 48 | return p.operandA + p.operandB 49 | } 50 | 51 | // MultiOperatorFactory 是乘法运算器产品的工厂 52 | type MultiOperatorFactory struct {} 53 | 54 | func (mf *MultiOperatorFactory) Create() MathOperator{ 55 | return &MultiOperator{ 56 | BaseOperator: &BaseOperator{}, 57 | } 58 | } 59 | 60 | // MultiOperator 实际的产品类--乘法运算器 61 | type MultiOperator struct { 62 | *BaseOperator 63 | } 64 | func (m *MultiOperator) ComputeResult() int { 65 | return m.operandA * m.operandB 66 | } 67 | 68 | 69 | // 测试运行 70 | func main() { 71 | var factory OperatorFactory 72 | var mathOp MathOperator 73 | factory = &PlusOperatorFactory{} 74 | mathOp = factory.Create() 75 | mathOp.SetOperandB(3) 76 | mathOp.SetOperandA(2) 77 | fmt.Printf("Plus operation reuslt: %d\n", mathOp.ComputeResult()) 78 | 79 | factory= &MultiOperatorFactory{} 80 | mathOp = factory.Create() 81 | mathOp.SetOperandB(3) 82 | mathOp.SetOperandA(2) 83 | fmt.Printf("Multiple operation reuslt: %d\n", mathOp.ComputeResult()) 84 | } 85 | -------------------------------------------------------------------------------- /src/factory/simple-factory/demo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // Printer 简单工厂要返回的接口类型 6 | type Printer interface { 7 | Print(name string) string 8 | } 9 | 10 | func NewPrinter(lang string) Printer { 11 | switch lang { 12 | case "cn": 13 | return new(CnPrinter) 14 | case "en": 15 | return new(EnPrinter) 16 | default: 17 | return new(CnPrinter) 18 | } 19 | } 20 | 21 | // CnPrinter 是 Printer 接口的实现,它说中文 22 | type CnPrinter struct {} 23 | 24 | func (*CnPrinter) Print(name string) string { 25 | return fmt.Sprintf("你好, %s", name) 26 | } 27 | 28 | // EnPrinter 是 Printer 接口的实现,它说中文 29 | type EnPrinter struct {} 30 | 31 | func (*EnPrinter) Print(name string) string { 32 | return fmt.Sprintf("Hello, %s", name) 33 | } 34 | 35 | func main() { 36 | printer := NewPrinter("en") 37 | fmt.Println(printer.Print("Bob")) 38 | } 39 | -------------------------------------------------------------------------------- /src/flyweight/flyweight.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | var pokerCards = map[int]*Card{ 6 | 1: { 7 | Name: "A", 8 | Color: "紅", 9 | }, 10 | 2: { 11 | Name: "A", 12 | Color: "黑", 13 | }, 14 | // 其他卡牌 15 | } 16 | 17 | type Card struct { 18 | Name string 19 | Color string 20 | } 21 | 22 | type PokerGame struct { 23 | Cards map[int]*Card 24 | } 25 | 26 | func NewPokerGame() *PokerGame { 27 | board := &PokerGame{Cards: map[int]*Card{}} 28 | for id := range pokerCards { 29 | board.Cards[id] = pokerCards[id] 30 | } 31 | return board 32 | } 33 | 34 | func main() { 35 | game1 := NewPokerGame() 36 | game2 := NewPokerGame() 37 | fmt.Println(game1.Cards[1] == game2.Cards[1]) 38 | } 39 | -------------------------------------------------------------------------------- /src/interpreter/code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | type Expression interface { 11 | Interpret() int 12 | } 13 | 14 | type NumberExpression struct { 15 | val int 16 | } 17 | 18 | func (n *NumberExpression) Interpret() int { 19 | return n.val 20 | } 21 | 22 | type AdditionExpression struct { 23 | left, right Expression 24 | } 25 | 26 | func (n *AdditionExpression) Interpret() int { 27 | return n.left.Interpret() + n.right.Interpret() 28 | } 29 | 30 | type SubtractionExpression struct { 31 | left, right Expression 32 | } 33 | 34 | func (n *SubtractionExpression) Interpret() int { 35 | return n.left.Interpret() - n.right.Interpret() 36 | } 37 | 38 | type Parser struct { 39 | exp []string 40 | index int 41 | prev Expression 42 | } 43 | 44 | func (p *Parser) Parse(exp string) { 45 | p.exp = strings.Split(exp, " ") 46 | 47 | for { 48 | if p.index >= len(p.exp) { 49 | return 50 | } 51 | switch p.exp[p.index] { 52 | case "+": 53 | p.prev = p.newAdditionExpression() 54 | case "-": 55 | p.prev = p.newSubtractionExpression() 56 | default: 57 | p.prev = p.newNumberExpression() 58 | } 59 | } 60 | } 61 | 62 | func (p *Parser) newAdditionExpression() Expression { 63 | p.index++ 64 | return &AdditionExpression{ 65 | left: p.prev, 66 | right: p.newNumberExpression(), 67 | } 68 | } 69 | 70 | func (p *Parser) newSubtractionExpression() Expression { 71 | p.index++ 72 | return &SubtractionExpression{ 73 | left: p.prev, 74 | right: p.newNumberExpression(), 75 | } 76 | } 77 | 78 | func (p *Parser) newNumberExpression() Expression { 79 | v, _ := strconv.Atoi(p.exp[p.index]) 80 | p.index++ 81 | return &NumberExpression{ 82 | val: v, 83 | } 84 | } 85 | 86 | func (p *Parser) Result() Expression { 87 | return p.prev 88 | } 89 | 90 | func main() { 91 | p := &Parser{} 92 | p.Parse("1 + 3 + 3 + 3 - 3") 93 | res := p.Result().Interpret() 94 | expect := 7 95 | if res != expect { 96 | log.Fatalf("error: expect %d got %d", expect, res) 97 | } 98 | 99 | fmt.Printf("expect: %d, got: %d", expect, res) 100 | } 101 | -------------------------------------------------------------------------------- /src/iterator/iterator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type collection interface { 6 | createIterator() iterator 7 | } 8 | 9 | type iterator interface { 10 | hasNext() bool 11 | getNext() *User 12 | } 13 | 14 | type User struct { 15 | name string 16 | age int 17 | } 18 | 19 | type userCollection struct { 20 | users []*User 21 | } 22 | 23 | func (u *userCollection) createIterator() iterator { 24 | return &userIterator{ 25 | users: u.users, 26 | } 27 | } 28 | 29 | type userIterator struct { 30 | index int 31 | users []*User 32 | } 33 | 34 | func (ui *userIterator) hasNext() bool { 35 | return ui.index < len(ui.users) 36 | } 37 | 38 | func (ui *userIterator) getNext() *User { 39 | if ui.hasNext() { 40 | user := ui.users[ui.index] 41 | ui.index++ 42 | return user 43 | } 44 | 45 | return nil 46 | } 47 | 48 | 49 | func main() { 50 | userK := &User{ 51 | name: "Kevin", 52 | age: 30, 53 | } 54 | userD := &User{ 55 | name: "Diamond", 56 | age: 25, 57 | } 58 | 59 | userCollection := &userCollection{ 60 | users: []*User{userK, userD}, 61 | } 62 | 63 | iterator := userCollection.createIterator() 64 | for iterator.hasNext() { 65 | user := iterator.getNext() 66 | fmt.Printf("User is %v\n", user) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/mediator/code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 中介者--机场指挥塔的接口定义 6 | type mediator interface { 7 | canLanding(airplane airplane) bool 8 | notifyAboutDeparture() 9 | } 10 | 11 | // 组件--飞行器的接口定义 12 | type airplane interface { 13 | landing() 14 | takeOff() 15 | permitLanding() 16 | } 17 | 18 | // 组件1--波音飞机 19 | type boeingPlane struct { 20 | mediator 21 | } 22 | 23 | func (b *boeingPlane) landing() { 24 | if !b.mediator.canLanding(b) { 25 | fmt.Println("Airplane Boeing: 飞机跑到正在被占用,无法降落!") 26 | return 27 | } 28 | fmt.Println("Airplane Boeing: 已成功降落!") 29 | } 30 | 31 | func (b *boeingPlane)takeOff() { 32 | fmt.Println("Airplane Boeing: 正在起飞离开跑道!") 33 | b.mediator.notifyAboutDeparture() 34 | } 35 | 36 | func (b *boeingPlane)permitLanding() { 37 | fmt.Println("Airplane Boeing: 收到指挥塔信号,允许降落,正在降落!") 38 | b.landing() 39 | 40 | } 41 | 42 | // 组件2--空客飞机 43 | type airBusPlane struct { 44 | mediator mediator 45 | } 46 | 47 | func (airbus *airBusPlane) landing() { 48 | if !airbus.mediator.canLanding(airbus) { 49 | fmt.Println("Airplane AirBus: 飞机跑到正在被占用,无法降落!") 50 | return 51 | } 52 | fmt.Println("Airplane AirBus: 已成功降落!") 53 | } 54 | 55 | func (airbus *airBusPlane) takeOff() { 56 | fmt.Println("Airplane AirBus: 正在起飞离开跑道!") 57 | airbus.mediator.notifyAboutDeparture() 58 | } 59 | 60 | func (airbus *airBusPlane)permitLanding() { 61 | fmt.Println("Airplane AirBus: 收到指挥塔信号,允许降落,正在降落!") 62 | airbus.landing() 63 | } 64 | 65 | // 中介者实现--指挥塔 66 | type manageTower struct { 67 | isRunwayFree bool 68 | airportQueue []airplane 69 | } 70 | 71 | func (tower *manageTower) canLanding(airplane airplane) bool { 72 | if tower.isRunwayFree { 73 | // 跑道空闲,允许降落,同时把状态变为繁忙 74 | tower.isRunwayFree = false 75 | return true 76 | } 77 | // 跑道繁忙,把飞机加入等待通知的队列 78 | tower.airportQueue = append(tower.airportQueue, airplane) 79 | return false 80 | } 81 | 82 | func (tower *manageTower) notifyAboutDeparture() { 83 | if !tower.isRunwayFree { 84 | tower.isRunwayFree = true 85 | } 86 | if len(tower.airportQueue) > 0 { 87 | firstPlaneInWaitingQueue := tower.airportQueue[0] 88 | tower.airportQueue = tower.airportQueue[1:] 89 | firstPlaneInWaitingQueue.permitLanding() 90 | } 91 | } 92 | 93 | func newManageTower() *manageTower { 94 | return &manageTower{ 95 | isRunwayFree: true, 96 | } 97 | } 98 | 99 | 100 | 101 | func main() { 102 | tower := newManageTower() 103 | boeing := &boeingPlane{ 104 | mediator: tower, 105 | } 106 | airbus := &airBusPlane{ 107 | mediator: tower, 108 | } 109 | boeing.landing() 110 | airbus.landing() 111 | boeing.takeOff() 112 | } 113 | -------------------------------------------------------------------------------- /src/memento/memento.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | // 编辑器接口定义 10 | type IEditor interface { 11 | Title(title string) 12 | Content(content string) 13 | Save() 14 | Undo() error 15 | Redo() error 16 | Show() 17 | } 18 | // 定义编辑器的备忘录, 也就是编辑器的内部状态数据模型, 同时也对应一个历史版本 19 | type EditorMemento struct { 20 | title string 21 | content string 22 | createTime int64 23 | } 24 | 25 | func newEditorMemento(title string, content string) *EditorMemento { 26 | return &EditorMemento{ 27 | title, content, time.Now().Unix(), 28 | } 29 | } 30 | 31 | // 编辑器类, 实现IEditor接口 32 | type Editor struct { 33 | title string 34 | content string 35 | versions []*EditorMemento 36 | index int 37 | } 38 | 39 | func NewEditor() IEditor { 40 | return &Editor{ 41 | "", "", make([]*EditorMemento, 0), 0, 42 | } 43 | } 44 | 45 | func (editor *Editor) Title(title string) { 46 | editor.title = title 47 | } 48 | 49 | func (editor *Editor) Content(content string) { 50 | editor.content = content 51 | } 52 | 53 | func (editor *Editor) Save() { 54 | it := newEditorMemento(editor.title, editor.content) 55 | editor.versions = append(editor.versions, it) 56 | editor.index = len(editor.versions) - 1 57 | } 58 | 59 | func (editor *Editor) Undo() error { 60 | return editor.load(editor.index - 1) 61 | } 62 | 63 | func (editor *Editor) load(i int) error { 64 | size := len(editor.versions) 65 | if size <= 0 { 66 | return errors.New("no history versions") 67 | } 68 | 69 | if i < 0 || i >= size { 70 | return errors.New("no more history versions") 71 | } 72 | 73 | it := editor.versions[i] 74 | editor.title = it.title 75 | editor.content = it.content 76 | editor.index = i 77 | return nil 78 | } 79 | 80 | func (editor *Editor) Redo() error { 81 | return editor.load(editor.index + 1) 82 | } 83 | 84 | func (editor *Editor) Show() { 85 | fmt.Printf("tMockEditor.Show, title=%s, content=%s\n", editor.title, editor.content) 86 | } 87 | 88 | func main() { 89 | editor := NewEditor() 90 | 91 | // test save() 92 | editor.Title("唐诗") 93 | editor.Content("白日依山尽") 94 | editor.Save() 95 | 96 | editor.Title("唐诗 登鹳雀楼") 97 | editor.Content("白日依山尽, 黄河入海流. ") 98 | editor.Save() 99 | 100 | editor.Title("唐诗 登鹳雀楼 王之涣") 101 | editor.Content("白日依山尽, 黄河入海流。欲穷千里目, 更上一层楼。") 102 | editor.Save() 103 | 104 | // test show() 105 | fmt.Println("-------------Editor 当前内容-----------") 106 | editor.Show() 107 | 108 | fmt.Println("-------------Editor 回退内容-----------") 109 | for { 110 | e := editor.Undo() 111 | if e != nil { 112 | break 113 | } else { 114 | editor.Show() 115 | } 116 | } 117 | 118 | fmt.Println("-------------Editor 前进内容-----------") 119 | for { 120 | e := editor.Redo() 121 | if e != nil { 122 | break 123 | } else { 124 | editor.Show() 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/observer/README.md: -------------------------------------------------------------------------------- 1 | ### 代码阅读指南 2 | 3 | `observer.go` 观察者模式最基础的 Go 实现版本。 4 | 5 | `event_dispatcher` 应用观察者模式实现的事件分发器,只供学习用 6 | 想在项目里应该: 7 | - 基于它进行改造,可参考Spring 的Event 结构,建议同时支持异步和同步两种事件处理方式 8 | -------------------------------------------------------------------------------- /src/observer/event_dispatcher.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // 事件类型基类 9 | type Event struct { 10 | //事件触发实例 11 | Target IEventDispatcher 12 | //事件类型 13 | Type string 14 | //事件携带数据源 15 | Object interface{} 16 | } 17 | 18 | // 事件调度器基类 19 | type EventDispatcher struct { 20 | savers []*EventSaver 21 | } 22 | 23 | // 事件调度器中存放的单元 24 | type EventSaver struct { 25 | Type string 26 | Listeners []*EventListener 27 | } 28 | 29 | // 监听器 30 | type EventListener struct { 31 | Handler EventHandler 32 | } 33 | 34 | // 监听器函数 35 | type EventHandler func(event Event) 36 | 37 | // 事件调度接口 38 | type IEventDispatcher interface { 39 | //事件监听 40 | AddEventListener(eventType string, listener *EventListener) 41 | //移除事件监听 42 | RemoveEventListener(eventType string, listener *EventListener) bool 43 | //是否包含事件 44 | HasEventListener(eventType string) bool 45 | //事件派发 46 | DispatchEvent(event Event) bool 47 | } 48 | 49 | // 创建事件派发器 50 | func NewEventDispatcher() *EventDispatcher { 51 | return new(EventDispatcher) 52 | } 53 | 54 | // 创建监听器 55 | func NewEventListener(h EventHandler) *EventListener { 56 | l := new(EventListener) 57 | l.Handler = h 58 | return l 59 | } 60 | 61 | // 创建事件 62 | func NewEvent(eventType string, object interface{}) Event { 63 | e := Event{Type:eventType, Object:object} 64 | return e 65 | } 66 | 67 | // 克隆事件 68 | func (this *Event)Clone() *Event { 69 | e := new(Event) 70 | e.Type = this.Type 71 | e.Target = e.Target 72 | return e 73 | } 74 | 75 | func (this *Event)ToString() string { 76 | return fmt.Sprintf("Event Type %v", this.Type) 77 | } 78 | 79 | // 事件调度器添加事件 80 | func (this *EventDispatcher)AddEventListener(eventType string, listener *EventListener) { 81 | for _, saver := range this.savers { 82 | if saver.Type == eventType { 83 | saver.Listeners = append(saver.Listeners, listener) 84 | return 85 | } 86 | } 87 | 88 | saver := &EventSaver{Type:eventType, Listeners:[]*EventListener{listener}} 89 | this.savers = append(this.savers, saver) 90 | } 91 | 92 | // 事件调度器移除某个监听 93 | func (this *EventDispatcher)RemoveEventListener(eventType string, listener *EventListener) bool { 94 | for _, saver := range this.savers { 95 | if saver.Type == eventType { 96 | for i, l := range saver.Listeners { 97 | if listener == l { 98 | saver.Listeners = append(saver.Listeners[:i], saver.Listeners[i + 1:]...) 99 | return true 100 | } 101 | } 102 | } 103 | } 104 | return false 105 | } 106 | 107 | // 事件调度器是否包含某个类型的监听 108 | func (this *EventDispatcher)HasEventListener(eventType string) bool { 109 | for _, saver := range this.savers { 110 | if saver.Type == eventType { 111 | return true 112 | } 113 | } 114 | return false 115 | } 116 | 117 | // 事件调度器派发事件 118 | func (this *EventDispatcher)DispatchEvent(event Event) bool { 119 | for _, saver := range this.savers { 120 | if saver.Type == event.Type { 121 | for _, listener := range saver.Listeners { 122 | event.Target = this 123 | listener.Handler(event) 124 | } 125 | return true 126 | } 127 | } 128 | return false 129 | } 130 | 131 | 132 | const HELLO_WORLD = "helloWorld" 133 | 134 | func main() { 135 | dispatcher := NewEventDispatcher() 136 | listener := NewEventListener(myEventListener) 137 | dispatcher.AddEventListener(HELLO_WORLD, listener) 138 | 139 | time.Sleep(time.Second * 2) 140 | //dispatcher.RemoveEventListener(HELLO_WORLD, listener) 141 | 142 | dispatcher.DispatchEvent(NewEvent(HELLO_WORLD, nil)) 143 | } 144 | 145 | func myEventListener(event Event) { 146 | fmt.Println(event.Type, event.Object, event.Target) 147 | } 148 | -------------------------------------------------------------------------------- /src/observer/observer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // Subject 接口,它相当于是发布者的定义 8 | type Subject interface { 9 | Subscribe(observer Observer) 10 | Notify(msg string) 11 | } 12 | 13 | // Observer 观察者接口 14 | type Observer interface { 15 | Update(msg string) 16 | } 17 | 18 | // Subject 实现 19 | type SubjectImpl struct { 20 | observers []Observer 21 | } 22 | 23 | // Subscribe 添加观察者(订阅者) 24 | func (sub *SubjectImpl) Subscribe(observer Observer) { 25 | sub.observers = append(sub.observers, observer) 26 | } 27 | 28 | 29 | // Notify 发布通知 30 | func (sub *SubjectImpl) Notify(msg string) { 31 | for _, o := range sub.observers { 32 | o.Update(msg) 33 | } 34 | } 35 | 36 | // Observer1 Observer1 37 | type Observer1 struct{} 38 | 39 | // Update 实现观察者接口 40 | func (Observer1) Update(msg string) { 41 | fmt.Printf("Observer1: %s\n", msg) 42 | } 43 | 44 | // Observer2 Observer2 45 | type Observer2 struct{} 46 | 47 | // Update 实现观察者接口 48 | func (Observer2) Update(msg string) { 49 | fmt.Printf("Observer2: %s\n", msg) 50 | } 51 | 52 | func main(){ 53 | sub := &SubjectImpl{} 54 | sub.Subscribe(&Observer1{}) 55 | sub.Subscribe(&Observer2{}) 56 | sub.Notify("Hello") 57 | } 58 | -------------------------------------------------------------------------------- /src/prototype/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | ) 7 | 8 | // Node a document object model node 9 | type Node interface { 10 | // Strings returns nodes text representation 11 | String() string 12 | // Parent returns the node parent 13 | Parent() Node 14 | // SetParent sets the node parent 15 | SetParent(node Node) 16 | // Children returns the node children nodes 17 | Children() []Node 18 | // AddChild adds a child node 19 | AddChild(child Node) 20 | // Clone clones a node 21 | Clone() Node 22 | } 23 | 24 | // Element represents an element in document object model 25 | type Element struct { 26 | text string 27 | parent Node 28 | children []Node 29 | } 30 | 31 | // NewElement makes a new element 32 | func NewElement(text string) *Element { 33 | return &Element{ 34 | text: text, 35 | parent: nil, 36 | children: make([]Node, 0), 37 | } 38 | } 39 | 40 | // Parent returns the element parent 41 | func (e *Element) Parent() Node { 42 | return e.parent 43 | } 44 | 45 | // SetParent sets the element parent 46 | func (e *Element) SetParent(node Node) { 47 | e.parent = node 48 | } 49 | 50 | // Children returns the element children elements 51 | func (e *Element) Children() []Node { 52 | return e.children 53 | } 54 | 55 | // AddChild adds a child element 56 | func (e *Element) AddChild(child Node) { 57 | copy := child.Clone() 58 | copy.SetParent(e) 59 | e.children = append(e.children, copy) 60 | } 61 | 62 | // Clone makes a copy of particular element. Note that the element becomes a 63 | // root of new orphan tree 64 | func (e *Element) Clone() Node { 65 | copy := &Element{ 66 | text: e.text, 67 | parent: nil, 68 | children: make([]Node, 0), 69 | } 70 | for _, child := range e.children { 71 | copy.AddChild(child) 72 | } 73 | return copy 74 | } 75 | 76 | // String returns string representation of element 77 | func (e *Element) String() string { 78 | buffer := bytes.NewBufferString(e.text) 79 | 80 | for _, c := range e.Children() { 81 | text := c.String() 82 | fmt.Fprintf(buffer, "\n %s", text) 83 | } 84 | 85 | return buffer.String() 86 | } 87 | 88 | 89 | 90 | func main() { 91 | // 职级节点--总监 92 | directorNode := NewElement("Director of Engineering") 93 | // 职级节点--研发经理 94 | engManagerNode := NewElement("Engineering Manager") 95 | engManagerNode.AddChild(NewElement("Lead Software Engineer")) 96 | // 研发经理是总监的下级 97 | directorNode.AddChild(engManagerNode) 98 | directorNode.AddChild(engManagerNode) 99 | // 办公室经理也是总监的下级 100 | officeManagerNode := NewElement("Office Manager") 101 | directorNode.AddChild(officeManagerNode) 102 | fmt.Println("") 103 | fmt.Println("# Company Hierarchy") 104 | fmt.Print(directorNode) 105 | fmt.Println("") 106 | // 从研发经理节点克隆出一颗新的树 107 | fmt.Println("# Team Hiearachy") 108 | fmt.Print(engManagerNode.Clone()) 109 | } 110 | -------------------------------------------------------------------------------- /src/proxy/proxy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Vehicle interface { 6 | Drive() 7 | } 8 | 9 | type Car struct{} 10 | 11 | func (c *Car) Drive() { 12 | fmt.Println("Car is being driven") 13 | } 14 | 15 | type Driver struct { 16 | Age int 17 | } 18 | 19 | type CarProxy struct { 20 | vehicle Vehicle 21 | driver *Driver 22 | } 23 | 24 | func NewCarProxy(driver *Driver) *CarProxy { 25 | return &CarProxy{&Car{}, driver} 26 | } 27 | 28 | func (c *CarProxy) Drive() { 29 | if c.driver.Age >= 16 { 30 | c.vehicle.Drive() 31 | } else { 32 | fmt.Println("Driver too young!") 33 | } 34 | } 35 | 36 | func main() { 37 | car := NewCarProxy(&Driver{12}) 38 | car.Drive() 39 | car2 := NewCarProxy(&Driver{22}) 40 | car2.Drive() 41 | } 42 | -------------------------------------------------------------------------------- /src/singleton/egger-mode/code.go: -------------------------------------------------------------------------------- 1 | package egger-mode 2 | 3 | // Singleton 饿汉式单例 4 | type Singleton struct{} 5 | 6 | var singleton *Singleton 7 | 8 | func init() { 9 | singleton = &Singleton{} 10 | } 11 | 12 | // GetInstance 获取实例 13 | func GetInstance() *Singleton { 14 | return singleton 15 | } 16 | -------------------------------------------------------------------------------- /src/singleton/lazy-mode/code.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type singleton struct{} 8 | 9 | var instance *singleton 10 | var once sync.Once 11 | 12 | // 懒汉模式单例 13 | func GetInstance() *singleton { 14 | once.Do(func() { 15 | instance = &singleton{} 16 | }) 17 | return instance 18 | } 19 | 20 | func main() { 21 | GetInstance() 22 | } 23 | -------------------------------------------------------------------------------- /src/state/state.go: -------------------------------------------------------------------------------- 1 | // State Pattern 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | // State interface 10 | type LightState interface { 11 | // 亮起当前状态的交通灯 12 | Light() 13 | // 转换到新状态的时候,调用的方法 14 | EnterState() 15 | // 设置一个状态要转变的状态 16 | NextLight(light *TrafficLight) 17 | // 检测车速 18 | CarPassingSpeed(*TrafficLight, int, string) 19 | } 20 | 21 | // Context 22 | type TrafficLight struct { 23 | State LightState 24 | SpeedLimit int 25 | } 26 | 27 | func NewSimpleTrafficLight(speedLimit int) *TrafficLight { 28 | return &TrafficLight{ 29 | SpeedLimit: speedLimit, 30 | State: NewRedState(), 31 | } 32 | } 33 | 34 | // 用于让具体LightState 嵌套实现类似继承的效果,减少公用法在每个具体 LightState 实现类中的重复实现 35 | // 它只实现LightState里的通用方法的默认版,不能实现所有的方法,那样的话他也就算一个 LightState 具体实现了, 36 | // 而这不是我们想要的,每个类型逻辑不同的关键方法以及覆盖默认版的通用方法的工作,留给具体类型去实现。 37 | type DefaultLightState struct { 38 | StateName string 39 | } 40 | 41 | // Draw 和 EnterState 的逻辑交给每个 LightState 的实现类来实现 42 | func (state *DefaultLightState) CarPassingSpeed(road *TrafficLight, speed int, licensePlate string) { 43 | if speed > road.SpeedLimit { 44 | fmt.Printf("Car with license %s was speeding\n", licensePlate) 45 | } 46 | } 47 | 48 | func (state *DefaultLightState) EnterState(){ 49 | fmt.Println("changed state to:", state.StateName) 50 | } 51 | 52 | func (tl *TrafficLight) TransitionState(newState LightState) { 53 | tl.State = newState 54 | tl.State.EnterState() 55 | } 56 | 57 | // 红灯状态 58 | type redState struct { 59 | DefaultLightState 60 | } 61 | 62 | func NewRedState() *redState { 63 | state := &redState{} 64 | state.StateName = "RED" 65 | return state 66 | } 67 | 68 | func (state *redState) Light() { 69 | fmt.Println("红灯亮起,不可行驶") 70 | } 71 | 72 | func (state *redState) CarPassingSpeed(light *TrafficLight, speed int, licensePlate string) { 73 | // 红灯时不能行驶, 所以这里要重写覆盖 DefaultLightState 里定义的这个方法 74 | if speed > 0 { 75 | fmt.Printf("Car with license \"%s\" ran a red light!\n", licensePlate) 76 | } 77 | } 78 | 79 | func (state *redState) NextLight(light *TrafficLight){ 80 | light.TransitionState(NewGreenState()) 81 | } 82 | 83 | // 绿灯状态 84 | type greenState struct{ 85 | DefaultLightState 86 | } 87 | 88 | func NewGreenState() *greenState{ 89 | state := &greenState{} 90 | state.StateName = "GREEN" 91 | return state 92 | } 93 | 94 | func (state *greenState) Light(){ 95 | fmt.Println("绿灯亮起,请行驶") 96 | } 97 | 98 | func (state *greenState) NextLight(light *TrafficLight){ 99 | light.TransitionState(NewAmberState()) 100 | } 101 | 102 | // 黄灯状态 103 | type amberState struct { 104 | DefaultLightState 105 | } 106 | 107 | func NewAmberState() *amberState{ 108 | state := &amberState{} 109 | state.StateName = "AMBER" 110 | return state 111 | } 112 | 113 | func (state *amberState) Light(){ 114 | fmt.Println("黄灯亮起,请注意") 115 | } 116 | 117 | func (state *amberState) NextLight(light *TrafficLight){ 118 | light.TransitionState(NewRedState()) 119 | } 120 | 121 | func main() { 122 | trafficLight := NewSimpleTrafficLight(500) 123 | 124 | interval := time.NewTicker(5 * time.Second) 125 | for { 126 | select { 127 | case <- interval.C: 128 | trafficLight.State.Light() 129 | trafficLight.State.CarPassingSpeed(trafficLight, 25, "CN1024") 130 | trafficLight.State.NextLight(trafficLight) 131 | default: 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/strategy/strategy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type PayBehavior interface { 6 | OrderPay(px *PayCtx) 7 | } 8 | 9 | // 具体支付策略实现 10 | // 微信支付 11 | type WxPay struct {} 12 | func(*WxPay) OrderPay(px *PayCtx) { 13 | fmt.Printf("Wx支付加工支付请求 %v\n", px.payParams) 14 | fmt.Println("正在使用Wx支付进行支付") 15 | } 16 | 17 | // 三方支付 18 | type ThirdPay struct {} 19 | func(*ThirdPay) OrderPay(px *PayCtx) { 20 | fmt.Printf("三方支付加工支付请求 %v\n", px.payParams) 21 | fmt.Println("正在使用三方支付进行支付") 22 | } 23 | 24 | type PayCtx struct { 25 | // 提供支付能力的接口实现 26 | payBehavior PayBehavior 27 | // 支付参数 28 | payParams map[string]interface{} 29 | } 30 | 31 | func (px *PayCtx) setPayBehavior(p PayBehavior) { 32 | px.payBehavior = p 33 | } 34 | 35 | func (px *PayCtx) Pay() { 36 | px.payBehavior.OrderPay(px) 37 | } 38 | 39 | func NewPayCtx(p PayBehavior) *PayCtx { 40 | // 支付参数,Mock数据 41 | params := map[string]interface{} { 42 | "appId": "234fdfdngj4", 43 | "mchId": 123456, 44 | } 45 | return &PayCtx{ 46 | payBehavior: p, 47 | payParams: params, 48 | } 49 | } 50 | 51 | func main() { 52 | wxPay := &WxPay{} 53 | px := NewPayCtx(wxPay) 54 | px.Pay() 55 | // 假设现在发现微信支付没钱,改用三方支付进行支付 56 | thPay := &ThirdPay{} 57 | px.setPayBehavior(thPay) 58 | px.Pay() 59 | } 60 | -------------------------------------------------------------------------------- /src/template/template_pattern.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | type BankBusinessHandler interface { 11 | // 排队拿号 12 | TakeRowNumber() 13 | // 等位 14 | WaitInHead() 15 | // 处理具体业务 16 | HandleBusiness() 17 | // 对服务作出评价 18 | Commentate() 19 | // 钩子方法,判断是不是VIP, VIP不用等位 20 | CheckVipIdentity() bool 21 | } 22 | 23 | 24 | type BankBusinessExecutor struct { 25 | handler BankBusinessHandler 26 | } 27 | // 模板方法,处理银行业务 28 | func (b *BankBusinessExecutor) ExecuteBankBusiness () { 29 | // 适用于与客户端单次交互的流程 30 | // 如果需要与客户端多次交互才能完成整个流程,每次交互的操作去对应模板里定义的方法就好,并不需要一个调用所有方法的模板方法 31 | b.handler.TakeRowNumber() 32 | if !b.handler.CheckVipIdentity() { 33 | b.handler.WaitInHead() 34 | } 35 | b.handler.HandleBusiness() 36 | b.handler.Commentate() 37 | } 38 | 39 | type DepositBusinessHandler struct { 40 | *DefaultBusinessHandler 41 | userVip bool 42 | } 43 | 44 | func (*DepositBusinessHandler) HandleBusiness() { 45 | fmt.Println("账户存储很多万人民币...") 46 | } 47 | 48 | func (dh *DepositBusinessHandler) CheckVipIdentity() bool { 49 | return dh.userVip 50 | } 51 | 52 | 53 | type DefaultBusinessHandler struct { 54 | } 55 | func (*DefaultBusinessHandler) TakeRowNumber() { 56 | fmt.Println("请拿好您的取件码:" + strconv.Itoa(rand.Intn(100)) + 57 | " ,注意排队情况,过号后顺延三个安排") 58 | } 59 | 60 | func (dbh *DefaultBusinessHandler) WaitInHead() { 61 | fmt.Println("排队等号中...") 62 | time.Sleep(5 * time.Second) 63 | fmt.Println("请去窗口xxx...") 64 | } 65 | 66 | func (*DefaultBusinessHandler) Commentate() { 67 | 68 | fmt.Println("请对我的服务作出评价,满意请按0,满意请按0,(~ ̄▽ ̄)~") 69 | } 70 | 71 | func (*DefaultBusinessHandler) CheckVipIdentity() bool { 72 | // 留给具体实现类实现 73 | return false 74 | } 75 | 76 | func NewBankBusinessExecutor(businessHandler BankBusinessHandler) *BankBusinessExecutor { 77 | return &BankBusinessExecutor {handler: businessHandler} 78 | } 79 | 80 | func main() { 81 | dh := &DepositBusinessHandler{userVip: false} 82 | bbe := NewBankBusinessExecutor(dh) 83 | bbe.ExecuteBankBusiness() 84 | } 85 | -------------------------------------------------------------------------------- /src/visitor/visitor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 订单实体类,实现IOrderService 接口 6 | type Order struct { 7 | ID int 8 | Customer string 9 | City string 10 | Product string 11 | Quantity int 12 | } 13 | 14 | func NewOrder(id int, customer string, city string, product string, quantity int) *Order { 15 | return &Order{ 16 | id, customer,city,product,quantity, 17 | } 18 | } 19 | 20 | // 订单服务接口 21 | type IOrderService interface { 22 | Save(order *Order) error 23 | // 有的教程里把接收 visitor 实现的方法名定义成 Accept 24 | Accept(visitor IOrderVisitor) 25 | } 26 | 27 | type IOrderVisitor interface { 28 | // 这里参数不能定义成 IOrderService 29 | Visit(order *Order) 30 | Report() 31 | } 32 | 33 | // 销售订单服务,实现IOrderService接口 34 | type OrderService struct { 35 | orders map[int]*Order 36 | } 37 | 38 | func (mo *OrderService) Save(o *Order) error { 39 | mo.orders[o.ID] = o 40 | return nil 41 | } 42 | 43 | func (mo *OrderService) Accept(visitor IOrderVisitor) { 44 | for _, v := range mo.orders { 45 | visitor.Visit(v) 46 | } 47 | } 48 | 49 | func NewOrderService() IOrderService { 50 | return &OrderService{ 51 | orders: make(map[int]*Order, 0), 52 | } 53 | } 54 | 55 | // 区域销售报表, 按城市汇总销售情况, 实现IOrderVisitor接口 56 | type CityVisitor struct { 57 | cities map[string]int 58 | } 59 | 60 | func (cv *CityVisitor) Visit(o *Order) { 61 | n, ok := cv.cities[o.City] 62 | if ok { 63 | cv.cities[o.City] = n + o.Quantity 64 | } else { 65 | cv.cities[o.City] = o.Quantity 66 | } 67 | } 68 | 69 | func (cv *CityVisitor) Report() { 70 | for k,v := range cv.cities { 71 | fmt.Printf("city=%s, sum=%v\n", k, v) 72 | } 73 | } 74 | 75 | func NewCityVisitor() IOrderVisitor { 76 | return &CityVisitor{ 77 | cities: make(map[string]int, 0), 78 | } 79 | } 80 | 81 | // 品类销售报表, 按产品汇总销售情况, 实现ISaleOrderVisitor接口 82 | type ProductVisitor struct { 83 | products map[string]int 84 | } 85 | 86 | func (pv *ProductVisitor) Visit(it *Order) { 87 | n,ok := pv.products[it.Product] 88 | if ok { 89 | pv.products[it.Product] = n + it.Quantity 90 | } else { 91 | pv.products[it.Product] = it.Quantity 92 | } 93 | } 94 | 95 | func (pv *ProductVisitor) Report() { 96 | for k,v := range pv.products { 97 | fmt.Printf("product=%s, sum=%v\n", k, v) 98 | } 99 | } 100 | 101 | func NewProductVisitor() IOrderVisitor { 102 | return &ProductVisitor{ 103 | products: make(map[string]int,0), 104 | } 105 | } 106 | 107 | 108 | func main() { 109 | orderService := NewOrderService() 110 | orderService.Save(NewOrder(1, "张三", "广州", "电视", 10)) 111 | orderService.Save(NewOrder(2, "李四", "深圳", "冰箱", 20)) 112 | orderService.Save(NewOrder(3, "王五", "东莞", "空调", 30)) 113 | orderService.Save(NewOrder(4, "张三三", "广州", "空调", 10)) 114 | orderService.Save(NewOrder(5, "李四四", "深圳", "电视", 20)) 115 | orderService.Save(NewOrder(6, "王五五", "东莞", "冰箱", 30)) 116 | 117 | cv := NewCityVisitor() 118 | orderService.Accept(cv) 119 | cv.Report() 120 | 121 | pv := NewProductVisitor() 122 | orderService.Accept(pv) 123 | pv.Report() 124 | } 125 | --------------------------------------------------------------------------------