├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── main.go └── pattern ├── AbstractFactory.go ├── Adapter.go ├── Bridge.go ├── Builder.go ├── ChainOfResponsibility.go ├── Command.go ├── Composite.go ├── Decorator.go ├── Facade.go ├── Factory.go ├── Flyweight.go ├── Interpreter.go ├── Iterator.go ├── Mediator.go ├── Memento.go ├── Observer.go ├── Prototype.go ├── Proxy.go ├── README.md ├── Singleton.go ├── Singleton2.go ├── State.go ├── Strategy.go ├── Template.go ├── Visitor.go └── doc.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.6 5 | 6 | install: 7 | - go get golang.org/x/tools/cmd/cover 8 | - go get github.com/mattn/goveralls 9 | 10 | script: 11 | - go build github.com/BPing/golang_design_pattern/pattern 12 | 13 | 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # golang_design_pattern 2 | Code to achieve the design model with golang 3 | 4 | [![Stargazers over time](https://starcharts.herokuapp.com/BPing/golang_design_pattern.svg)](https://starcharts.herokuapp.com/BPing/golang_design_pattern) 5 | 6 | # 设计模式 7 | 用golang语言实现设计模式 8 | 9 | # 设计模式的六大原则 10 | 11 | 摘自 [Java开发中的23种设计模式详解](http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html) 12 | 13 | * 1、开闭原则(Open Close Principle) 14 | 15 | 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。 16 | 所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后 17 | 面的具体设计中我们会提到这点。 18 | 19 | * 2、里氏代换原则(Liskov Substitution Principle) 20 | 21 | 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何 22 | 基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受 23 | 到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。 24 | 实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽 25 | 象化的具体步骤的规范。—— From Baidu 百科 26 | 27 | * 3、依赖倒转原则(Dependence Inversion Principle) 28 | 29 | 这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。 30 | 31 | * 4、接口隔离原则(Interface Segregation Principle) 32 | 33 | 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出, 34 | 其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。 35 | 36 | * 5、迪米特法则(最少知道原则)(Demeter Principle) 37 | 38 | 为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 39 | 40 | * 6、合成复用原则(Composite Reuse Principle) 41 | 42 | 原则是尽量使用合成/聚合的方式,而不是使用继承。 43 | 44 | # 文档 45 | https://godoc.org/github.com/BPing/golang_design_pattern/pattern [![GoDoc](https://godoc.org/github.com/BPing/golang_design_pattern/pattern?status.svg)](https://godoc.org/github.com/BPing/golang_design_pattern/pattern) 46 | 47 | # 同类项目(golang) 48 | [go-pattern](https://github.com/tmrts/go-patterns) 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/BPing/golang_design_pattern/pattern" 5 | ) 6 | 7 | func main() { 8 | 9 | var battery pattern.RechargeableBattery 10 | 11 | battery = pattern.AdapterNonToYes{pattern.NonRechargeableA{}} 12 | battery.Use() 13 | battery.Charge() 14 | 15 | battery = pattern.NonRechargeableB{} 16 | battery.Use() 17 | battery.Charge() 18 | 19 | } 20 | -------------------------------------------------------------------------------- /pattern/AbstractFactory.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | 4 | //抽象工厂 5 | type AbstractFactory interface { 6 | Produce() pen //生产笔 7 | } 8 | 9 | type PencilFactory struct { 10 | } 11 | 12 | func (PencilFactory) Produce() pen { 13 | return new(pencil) 14 | } 15 | 16 | type BrushPen struct { 17 | } 18 | 19 | func (BrushPen) Produce() pen { 20 | return new(brushPen) 21 | } 22 | -------------------------------------------------------------------------------- /pattern/Adapter.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 6 | // 适配器模式 7 | // 是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 8 | // 或者 9 | // 将一个类的接口转换成客户希望的另外一个接口。 10 | // Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 11 | // 12 | // 主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式 13 | // 14 | 15 | //不可充电电池使用接口 16 | type NonRechargeableBattery interface { 17 | Use() 18 | } 19 | 20 | //可充电电池使用接口 21 | type RechargeableBattery interface { 22 | Use() 23 | Charge() 24 | } 25 | 26 | //不可充电电池A 27 | type NonRechargeableA struct { 28 | } 29 | 30 | func (NonRechargeableA) Use() { 31 | fmt.Println("NonRechargeableA using ") 32 | } 33 | 34 | //类的适配器模式 35 | // 似乎golang语言层面已经支持了,暂且搁置 36 | // 37 | // 38 | 39 | //对象的适配器模式 40 | 41 | //适配可充电电池使用接口 42 | type AdapterNonToYes struct { 43 | NonRechargeableBattery 44 | } 45 | 46 | func (AdapterNonToYes) Charge() { 47 | fmt.Println("AdapterNonToYes Charging") 48 | //nothing to do ,just adapt for RechargeableBattery's interface 49 | } 50 | 51 | //接口的适配器模式 52 | 53 | type RechargeableBatteryAbstract struct { 54 | } 55 | 56 | func (RechargeableBatteryAbstract) Use() { 57 | fmt.Println("RechargeableBatteryAbstract using") 58 | } 59 | func (RechargeableBatteryAbstract) Charge() { 60 | fmt.Println("RechargeableBatteryAbstract Charging") 61 | } 62 | 63 | type NonRechargeableB struct { 64 | RechargeableBatteryAbstract 65 | } 66 | 67 | func (NonRechargeableB) Use() { 68 | fmt.Println("NonRechargeableB using ") 69 | } 70 | 71 | //test 72 | func AdapterTest() { 73 | var battery RechargeableBattery 74 | 75 | battery = AdapterNonToYes{NonRechargeableA{}} 76 | battery.Use() 77 | battery.Charge() 78 | 79 | battery = NonRechargeableB{} 80 | battery.Use() 81 | battery.Charge() 82 | } 83 | -------------------------------------------------------------------------------- /pattern/Bridge.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | // 9 | // 桥接模式 10 | // 是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式, 11 | // 它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。 12 | // 13 | 14 | //请求接口 15 | type Request interface { 16 | HttpRequest() (*http.Request, error) 17 | } 18 | 19 | //客户端 20 | type Client struct { 21 | Client *http.Client 22 | } 23 | 24 | func (c *Client) Query(req Request) (resp *http.Response, err error) { 25 | httpreq,_:=req.HttpRequest() 26 | resp, err = c.Client.Do(httpreq) 27 | return 28 | } 29 | 30 | type CdnRequest struct { 31 | } 32 | 33 | func (cdn *CdnRequest) HttpRequest() (*http.Request, error) { 34 | return http.NewRequest("GET", "/cdn", nil) 35 | } 36 | 37 | type LiveRequest struct { 38 | } 39 | 40 | func (cdn *LiveRequest) HttpRequest() (*http.Request, error) { 41 | return http.NewRequest("GET", "/live", nil) 42 | } 43 | 44 | func TestBridge() { 45 | client := &Client{http.DefaultClient} 46 | 47 | cdnReq := &CdnRequest{} 48 | fmt.Println(client.Query(cdnReq)) 49 | 50 | liveReq := &LiveRequest{} 51 | fmt.Println(client.Query(liveReq)) 52 | } 53 | -------------------------------------------------------------------------------- /pattern/Builder.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | const ( 4 | FOOD = "food" 5 | DRINK = "drink" 6 | ) 7 | 8 | type Item interface { 9 | Price() float32 //价钱 10 | Name() string //名称 11 | Category() string //类别 12 | } 13 | 14 | //食物 15 | type Food struct { 16 | } 17 | 18 | func (Food) Price() float32 { 19 | return 0.0 20 | } 21 | func (Food) Name() string { 22 | return "" 23 | } 24 | func (Food) Category() string { 25 | return FOOD 26 | } 27 | 28 | //饮料 29 | type Drink struct { 30 | } 31 | 32 | func (Drink) Price() float32 { 33 | return 0.0 34 | } 35 | func (Drink) Name() string { 36 | return "" 37 | } 38 | func (Drink) Category() string { 39 | return DRINK 40 | } 41 | 42 | //汉堡 43 | type Hamburger struct { 44 | Food 45 | } 46 | 47 | func (Hamburger) Price() float32 { 48 | return 12.00 49 | } 50 | func (Hamburger) Name() string { 51 | return "Hamburger" 52 | } 53 | 54 | //炸鸡 55 | type FriedChicken struct { 56 | Food 57 | } 58 | 59 | func (FriedChicken) Price() float32 { 60 | return 18.00 61 | } 62 | func (FriedChicken) Name() string { 63 | return "FriedChicken" 64 | } 65 | 66 | //可乐 67 | type Cola struct { 68 | Drink 69 | } 70 | 71 | func (Cola) Price() float32 { 72 | return 3.00 73 | } 74 | func (Cola) Name() string { 75 | return "Cola" 76 | } 77 | 78 | //啤酒 79 | type Beer struct { 80 | Drink 81 | } 82 | 83 | func (Beer) Price() float32 { 84 | return 5.00 85 | } 86 | func (Beer) Name() string { 87 | return "Beer" 88 | } 89 | 90 | type Meal []Item 91 | 92 | func (this *Meal) AddItem(item ...Item) { 93 | *this = append(*this, item...) 94 | } 95 | 96 | func (this Meal) GetCost() (cost float32) { 97 | for _, val := range this { 98 | cost += val.Price() 99 | } 100 | return 101 | } 102 | func (this Meal) ShowItems() (msg string) { 103 | for _, val := range this { 104 | msg += "Category:" + val.Category() + " Name:" + val.Name() + "\n" 105 | } 106 | return 107 | } 108 | 109 | //建造者 110 | type MealBuilder struct { 111 | } 112 | 113 | func (MealBuilder) MealOne() (meal *Meal) { 114 | meal = new(Meal) 115 | meal.AddItem(new(FriedChicken), new(Beer)) 116 | return 117 | } 118 | -------------------------------------------------------------------------------- /pattern/ChainOfResponsibility.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 责任链模式 6 | // 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。 7 | // 将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 8 | // 9 | // github.com/BPing/Golib/middleware 包就是基于此模式实现的 10 | 11 | 12 | type ScreenEvent struct { 13 | Type string 14 | Comment string 15 | } 16 | 17 | type IScreenEventHandler interface{ 18 | Handle(*ScreenEvent)bool 19 | SetNextHandler(IScreenEventHandler) 20 | } 21 | 22 | type AbsScreenEventHandler struct { 23 | NextHandler IScreenEventHandler 24 | } 25 | 26 | func(ase *AbsScreenEventHandler)Handle(se *ScreenEvent)bool{ 27 | if ase.NextHandler!=nil { 28 | return ase.NextHandler.Handle(se) 29 | } 30 | return false 31 | } 32 | 33 | func(ase *AbsScreenEventHandler)SetNextHandler(ise IScreenEventHandler){ 34 | ase.NextHandler=ise 35 | } 36 | 37 | type HomeScreenEventHandler struct { 38 | AbsScreenEventHandler 39 | } 40 | 41 | func(hse *HomeScreenEventHandler)Handle(se *ScreenEvent)bool{ 42 | fmt.Println("HomeScreenEventHandler.....") 43 | if se.Type=="HomeClick" { 44 | fmt.Println("HomeClick") 45 | return true 46 | } 47 | return hse.AbsScreenEventHandler.Handle(se) 48 | } 49 | 50 | type UserScreenEventHandler struct { 51 | AbsScreenEventHandler 52 | } 53 | 54 | func(use *UserScreenEventHandler)Handle(se *ScreenEvent)bool{ 55 | fmt.Println("UserScreenEventHandler.....") 56 | if se.Type=="UserModelClick" { 57 | fmt.Println("UserModelClick") 58 | return true 59 | } 60 | return use.AbsScreenEventHandler.Handle(se) 61 | } 62 | 63 | func ChainOfResponsibilityTest(){ 64 | var osd IScreenEventHandler 65 | osd=&AbsScreenEventHandler{} 66 | home:=&HomeScreenEventHandler{} 67 | user:=&UserScreenEventHandler{} 68 | home.SetNextHandler(user) 69 | osd.SetNextHandler(home) 70 | 71 | screenEvent:=&ScreenEvent{Type:"HomeClick"} 72 | osd.Handle(screenEvent) 73 | 74 | fmt.Println("-----------------------------------------------\n") 75 | screenEvent=&ScreenEvent{Type:"UserModelClick"} 76 | osd.Handle(screenEvent) 77 | 78 | fmt.Println("-----------------------------------------------\n") 79 | screenEvent=&ScreenEvent{Type:"Null"} 80 | osd.Handle(screenEvent) 81 | } -------------------------------------------------------------------------------- /pattern/Command.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | // Command(命令) 9 | // 命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。 10 | // 请求以命令的形式包裹在对象中,并传给调用对象。 调用对象寻找可以处理该命令 11 | // 的合适的对象,并把该命令传给相应的对象,该对象执行命令。 12 | // 13 | 14 | // 命令接口 15 | type Command interface { 16 | Do(args interface{}) (interface{}, error) 17 | } 18 | 19 | // Get 命令 20 | type GetCommand struct { 21 | } 22 | 23 | func (gc *GetCommand) Do(args interface{}) (interface{}, error) { 24 | fmt.Println("GetCommand") 25 | return args, nil 26 | } 27 | 28 | // post 命令 29 | type PostCommand struct { 30 | } 31 | 32 | func (pc *PostCommand) Do(args interface{}) (interface{}, error) { 33 | fmt.Println("PostCommand") 34 | return args, nil 35 | } 36 | 37 | // 上下文 38 | type CmdContext struct { 39 | CmdType string 40 | Args interface{} 41 | } 42 | 43 | // 命令管理者 44 | type CommandHandler struct { 45 | CmdMap map[string]Command 46 | } 47 | 48 | // 处理命令 49 | func (ch *CommandHandler) Handle(ctx *CmdContext) (interface{}, error) { 50 | if ctx == nil { 51 | return nil, errors.New("") 52 | } 53 | cmd, ok := ch.CmdMap[ctx.CmdType] 54 | if ok { 55 | return cmd.Do(ctx.Args) 56 | } 57 | return nil, errors.New("invalid Command ") 58 | } 59 | 60 | // 注册命令 61 | func (ch *CommandHandler) Register(cmdType string, cmd Command) { 62 | ch.CmdMap[cmdType] = cmd 63 | } 64 | 65 | // 66 | func CommandTest() { 67 | cmdHandler := &CommandHandler{CmdMap: make(map[string]Command)} 68 | postCtx := &CmdContext{CmdType: "post", Args: " Post"} 69 | getCtx := &CmdContext{CmdType: "get", Args: " Get"} 70 | nullCtx := &CmdContext{CmdType: "null", Args: " Get"} 71 | cmdHandler.Register("post", &PostCommand{}) 72 | cmdHandler.Register("get", &GetCommand{}) 73 | 74 | fmt.Println(cmdHandler.Handle(postCtx)) 75 | fmt.Println(cmdHandler.Handle(getCtx)) 76 | fmt.Println(cmdHandler.Handle(nullCtx)) 77 | 78 | } 79 | -------------------------------------------------------------------------------- /pattern/Composite.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 6 | // 组合模式 将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 7 | // 8 | 9 | type Department struct { 10 | List map[string]*Department 11 | Parent *Department 12 | Name string 13 | Id string 14 | } 15 | 16 | // 批量添加子节点 17 | func (this *Department) Add(departments ...*Department) { 18 | for _, department := range departments { 19 | department.AddTo(this) 20 | } 21 | } 22 | 23 | // 添加到对应的父节点 24 | func (this *Department) AddTo(parent *Department) { 25 | this.Parent = parent 26 | parent.add(this) 27 | } 28 | 29 | // 添加子节点 30 | func (this *Department) add(department *Department) { 31 | this.List[department.Id] = department 32 | } 33 | 34 | // 查找子节点 35 | func (this *Department) Find(id string) (department *Department) { 36 | department, ok := this.List[id] 37 | if !ok { 38 | for _, de := range this.List { 39 | department = de.Find(id) 40 | if nil != department { 41 | return 42 | } 43 | } 44 | return 45 | } 46 | return 47 | } 48 | 49 | // 移除子节点 50 | func (this *Department) Remove(id string) (department *Department) { 51 | department, ok := this.List[id] 52 | if !ok { 53 | for _, de := range this.List { 54 | department = de.Remove(id) 55 | if nil != department { 56 | return 57 | } 58 | } 59 | return 60 | } 61 | delete(this.List, id) 62 | return 63 | } 64 | 65 | // 遍历 66 | func (this *Department) ReadList() { 67 | fmt.Printf("Node :%s(%s) \n the children: \n", this.Id, this.Name) 68 | for _, de := range this.List { 69 | de.ReadList() 70 | } 71 | } 72 | 73 | // example 74 | func CompositeTest() { 75 | root := &Department{Name: "root", Id: "0010"} 76 | children1 := &Department{Name: "network", Id: "00010"} 77 | children2 := &Department{Name: "forward", Id: "00011"} 78 | root.Add(children1, children2) 79 | children1.Add(&Department{Name: "network1", Id: "0001010"}) 80 | 81 | root.Find("0001010").ReadList() 82 | 83 | root.ReadList() 84 | 85 | root.Remove("00010").ReadList() 86 | 87 | root.ReadList() 88 | 89 | } 90 | -------------------------------------------------------------------------------- /pattern/Decorator.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "strings" 5 | "fmt" 6 | "log" 7 | ) 8 | 9 | // 10 | // 装饰模式 11 | // 动态地给一个对象添加一些额外的职责,同时又不改变其结构 12 | // 13 | 14 | // 接口 15 | type MessageBuilder interface{ 16 | Build(messages ... string) string 17 | } 18 | 19 | // 基本信息构造器 20 | type BaseMessageBuilder struct { 21 | 22 | } 23 | 24 | func(b *BaseMessageBuilder)Build(messages ... string) string{ 25 | return strings.Join(messages,",") 26 | } 27 | 28 | // 引号装饰器 29 | type QuoteMessageBuilderDecorator struct { 30 | Builder MessageBuilder 31 | } 32 | 33 | func(q *QuoteMessageBuilderDecorator)Build(messages ... string) string{ 34 | return "\""+q.Builder.Build(messages...)+"\"" 35 | } 36 | 37 | 38 | // 大括号装饰器 39 | type BraceMessageBuilderDecorator struct { 40 | Builder MessageBuilder 41 | } 42 | 43 | func(b *BraceMessageBuilderDecorator)Build(messages ... string) string{ 44 | return "{"+b.Builder.Build(messages...)+"}" 45 | } 46 | 47 | 48 | // 或者 49 | 50 | 51 | type Object func(int) int 52 | 53 | func LogDecorate(fn Object) Object { 54 | return func(n int) int { 55 | log.Println("Starting the execution with the integer", n) 56 | 57 | result := fn(n) 58 | 59 | log.Println("Execution is completed with the result", result) 60 | 61 | return result 62 | } 63 | } 64 | 65 | func Double(n int) int { 66 | return n * 2 67 | } 68 | 69 | 70 | // 调试 71 | func DecoratorTest(){ 72 | var MB MessageBuilder 73 | 74 | MB=&BaseMessageBuilder{} 75 | 76 | fmt.Println(MB.Build("hello world")) 77 | 78 | MB=&QuoteMessageBuilderDecorator{MB} 79 | 80 | fmt.Println(MB.Build("hello world")) 81 | 82 | MB=&BraceMessageBuilderDecorator{MB} 83 | 84 | fmt.Println(MB.Build("hello world")) 85 | 86 | 87 | // 88 | f := LogDecorate(Double) 89 | f(5) 90 | } -------------------------------------------------------------------------------- /pattern/Facade.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 6 | // 外观模式 7 | // 隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口 8 | // 9 | 10 | type Coder struct { 11 | } 12 | 13 | func (c *Coder) Coding() { 14 | fmt.Println("Coding ....") 15 | } 16 | 17 | type Tester struct { 18 | } 19 | 20 | func (t *Tester) Testing() { 21 | fmt.Println("Testing ....") 22 | } 23 | 24 | type ProductPlanner struct { 25 | } 26 | 27 | func (p *ProductPlanner) Planing() { 28 | fmt.Println("Planing ....") 29 | } 30 | 31 | type MaintenancePeople struct { 32 | } 33 | 34 | func (m *MaintenancePeople) Releasing() { 35 | fmt.Println("Releasing ....") 36 | } 37 | 38 | // 公司 39 | // 拥有产品策划、程序员、测试人员,运维人员 40 | // 通过公司这个外观对外提供服务, 41 | // 而不是直接通过某个类型人员对外服务(虽然最终提供服务的也是某个类型的人员) 42 | type Company struct { 43 | ProductPlanner 44 | Coder 45 | Tester 46 | MaintenancePeople 47 | } 48 | 49 | // 对外提供生产产品服务 50 | // 需要各个类型人员合作,但细节不对外公开的 51 | func (com *Company) Producing() { 52 | // 策划产品 53 | com.ProductPlanner.Planing() 54 | // 编码实现 55 | com.Coder.Coding() 56 | // 测试产品 57 | com.Tester.Testing() 58 | // 发布产品 59 | com.MaintenancePeople.Releasing() 60 | 61 | // 或者 62 | //com.Planing() 63 | //com.Coding() 64 | //com.Testing() 65 | //com.Releasing() 66 | } 67 | 68 | func FacadeTest() { 69 | com := &Company{} 70 | 71 | com.Producing() 72 | 73 | // 单独调用某个功能, 74 | // 通过公司外观提供的服务 75 | com.Testing() 76 | } 77 | -------------------------------------------------------------------------------- /pattern/Factory.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | //工厂模式适合:凡是出现了大量的产品需要创建, 4 | //并且具有共同的接口时,可以通过工厂方法模式进行创建 5 | import "fmt" 6 | 7 | //笔 8 | type pen interface { 9 | //写字 10 | Write() 11 | } 12 | 13 | type pencil struct { 14 | } 15 | 16 | func (p *pencil) Write() { 17 | fmt.Println("铅笔") 18 | } 19 | 20 | type brushPen struct { 21 | } 22 | 23 | func (p *brushPen) Write() { 24 | fmt.Println("毛笔") 25 | } 26 | 27 | //工厂 28 | type PenFactory struct { 29 | } 30 | 31 | func (this PenFactory) Produce(typ string) pen { 32 | switch typ { 33 | case "pencil": 34 | return this.ProducePencil() 35 | case "brush": 36 | return this.ProduceBrushPen() 37 | default: 38 | return nil 39 | } 40 | } 41 | 42 | func (PenFactory) ProducePencil() pen { 43 | return new(pencil) 44 | } 45 | 46 | func (PenFactory) ProduceBrushPen() pen { 47 | return new(brushPen) 48 | } 49 | -------------------------------------------------------------------------------- /pattern/Flyweight.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // 8 | // 享元模式 9 | // 实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。 10 | // sync.pool 就属于此模式 11 | // 12 | 13 | // 数据库连接池 14 | type DbConnectPool struct { 15 | ConnChan chan *DbConnect 16 | } 17 | 18 | func NewDbConnectPool(chanLen int)*DbConnectPool{ 19 | return &DbConnectPool{ConnChan:make(chan *DbConnect,chanLen)} 20 | } 21 | 22 | func(dc *DbConnectPool) Get()*DbConnect{ 23 | select { 24 | case conn := <-dc.ConnChan: 25 | return conn 26 | default: 27 | // 无则新建 28 | return new(DbConnect) 29 | } 30 | } 31 | func(dc *DbConnectPool) Put(conn *DbConnect){ 32 | select { 33 | case dc.ConnChan <- conn: 34 | return 35 | default: 36 | // 满则丢弃 37 | return 38 | } 39 | } 40 | 41 | // 数据库连接 42 | type DbConnect struct { 43 | 44 | } 45 | 46 | func (*DbConnect) Do(){ 47 | fmt.Println("connect......doing....") 48 | } 49 | 50 | 51 | func FlyweightTest(){ 52 | pool:=NewDbConnectPool(2) 53 | conn:=pool.Get() 54 | conn.Do() 55 | pool.Put(conn) 56 | } 57 | -------------------------------------------------------------------------------- /pattern/Interpreter.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "strings" 5 | "fmt" 6 | ) 7 | 8 | //解释器模式(Interpreter Pattern) 9 | // 提供了评估语言的语法或表达式的方式,文法解释,它属于行为型模式。 10 | // 这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。 11 | // 12 | // 一般递归处理 13 | 14 | 15 | 16 | type Expression interface { 17 | Interpret(context string) bool 18 | } 19 | 20 | type TerminalExpression struct { 21 | Word string 22 | } 23 | 24 | // 终结符 25 | func(te *TerminalExpression)Interpret(context string) bool{ 26 | if strings.Contains(context,te.Word) { 27 | return true 28 | } 29 | return false 30 | } 31 | 32 | // 或 33 | type OrExpression struct { 34 | A Expression 35 | B Expression 36 | } 37 | 38 | func(oe *OrExpression)Interpret(context string) bool{ 39 | return oe.A.Interpret(context)||oe.B.Interpret(context) 40 | } 41 | 42 | // 与 43 | type AndExpression struct { 44 | A Expression 45 | B Expression 46 | } 47 | 48 | func(ae *AndExpression )Interpret(context string) bool{ 49 | return ae.A.Interpret(context)&&ae.B.Interpret(context) 50 | } 51 | 52 | func InterpreterTest(){ 53 | isMale :=&OrExpression{&TerminalExpression{"Robert"},&TerminalExpression{"John"}} 54 | isMarriedWoman :=&AndExpression{&TerminalExpression{"Julie"},&TerminalExpression{"Married"}} 55 | fmt.Println("John is male?",isMale.Interpret("John")) 56 | fmt.Println("Julie is a married women?",isMarriedWoman.Interpret("Married Julie")) 57 | } -------------------------------------------------------------------------------- /pattern/Iterator.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 6 | // 迭代器模式(Iterator Pattern) 7 | // 这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。 8 | 9 | // 迭代器接口 10 | type Iterator interface { 11 | HasNext() bool 12 | Next() interface{} 13 | } 14 | 15 | // 集合接口 16 | type Container interface { 17 | GetIterator() Iterator 18 | } 19 | 20 | // 数组迭代器 21 | type ArrayIterator struct { 22 | currentIndex int 23 | ac *ArrayContainer 24 | } 25 | 26 | func (ai *ArrayIterator) HasNext() bool { 27 | if ai.ac.arrayData!=nil&&ai.currentIndex < len(ai.ac.arrayData) { 28 | return true 29 | } 30 | return false 31 | } 32 | 33 | func (ai *ArrayIterator) Next() interface{} { 34 | if ai.HasNext() { 35 | defer func() { ai.currentIndex++ }() 36 | return ai.ac.arrayData[ai.currentIndex] 37 | 38 | } 39 | return nil 40 | } 41 | 42 | // 数组集合 43 | type ArrayContainer struct { 44 | arrayData []interface{} 45 | } 46 | 47 | func (ac *ArrayContainer) GetIterator() Iterator { 48 | return &ArrayIterator{currentIndex: 0, ac: ac} 49 | } 50 | 51 | 52 | func IteratorTest(){ 53 | arr:=[]interface{}{"a","b","c","d"} 54 | arrayContainer:=&ArrayContainer{arrayData:arr} 55 | iterator:=arrayContainer.GetIterator() 56 | for iterator.HasNext(){ 57 | fmt.Println(iterator.Next().(string)) 58 | } 59 | } -------------------------------------------------------------------------------- /pattern/Mediator.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 中介者模式(Mediator Pattern) 6 | // 是用来降低多个对象和类之间的通信复杂性。 7 | // 这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护 8 | 9 | 10 | type ChatRoom struct { 11 | name string 12 | } 13 | 14 | func (cr *ChatRoom)SendMsg(msg string){ 15 | fmt.Println(cr.name+" : "+msg) 16 | } 17 | func (cr *ChatRoom)RegisterUser(u *User){ 18 | u.cr=cr 19 | } 20 | 21 | type User struct { 22 | name string 23 | cr *ChatRoom 24 | } 25 | 26 | func (u *User)SendMsg(msg string){ 27 | if u.cr!=nil { 28 | u.cr.SendMsg(u.name+" : "+msg) 29 | } 30 | } 31 | 32 | func MediatorTest(){ 33 | AUser:=&User{name:"AUser"} 34 | BUser:=&User{name:"BUser"} 35 | 36 | chatRoom:=&ChatRoom{name:"chatRoom123456"} 37 | chatRoom.RegisterUser(AUser) 38 | chatRoom.RegisterUser(BUser) 39 | 40 | AUser.SendMsg("hello AUser") 41 | BUser.SendMsg("hello BUser") 42 | 43 | } 44 | -------------------------------------------------------------------------------- /pattern/Memento.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "container/list" 5 | "fmt" 6 | ) 7 | 8 | // 备忘录模式(Memento pattern) 9 | // 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 10 | // 这样以后就可将该对象恢复到原先保存的状态。 11 | 12 | // 相关模式:原型模式 13 | 14 | // 文本编辑 15 | type Text struct { 16 | Value string 17 | } 18 | 19 | // 写 20 | func (t *Text) Write(value string) { 21 | t.Value = value 22 | } 23 | 24 | // 读取 25 | func (t *Text) Read() string { 26 | return t.Value 27 | } 28 | 29 | // 备忘 30 | func (t *Text) SaveToMemento() *Memento { 31 | return &Memento{Value: t.Value} 32 | } 33 | 34 | // 从备忘恢复 35 | func (t *Text) RestoreFromMemento(m *Memento) { 36 | if m!=nil { 37 | t.Value = m.Value 38 | } 39 | return 40 | } 41 | 42 | // 备忘结构 43 | type Memento struct { 44 | Value string 45 | } 46 | 47 | // 管理备忘记录 48 | type Storage struct { 49 | *list.List 50 | } 51 | 52 | // Back returns the last element of list l or nil. 53 | // and remove form list 54 | func (s *Storage)RPop()*list.Element{ 55 | ele:=s.Back() 56 | if ele!=nil{ 57 | s.Remove(ele) 58 | } 59 | return ele 60 | } 61 | 62 | 63 | func MementoTest(){ 64 | storage:=&Storage{list.New()} 65 | text:=&Text{"hello world"} 66 | fmt.Println(text.Read()) 67 | storage.PushBack(text.SaveToMemento()) 68 | text.Write("nihao") 69 | fmt.Println(text.Read()) 70 | storage.PushBack(text.SaveToMemento()) 71 | text.Write("i know") 72 | fmt.Println(text.Read()) 73 | 74 | //后退回滚 75 | mediator:=storage.RPop() 76 | if mediator!=nil { 77 | text.RestoreFromMemento(mediator.Value.(*Memento)) 78 | } 79 | fmt.Println(text.Read()) 80 | 81 | //后退回滚 82 | mediator=storage.RPop() 83 | if mediator!=nil { 84 | text.RestoreFromMemento(mediator.Value.(*Memento)) 85 | } 86 | fmt.Println(text.Read()) 87 | 88 | //后退 已没有 89 | mediator=storage.RPop() 90 | if mediator!=nil { 91 | text.RestoreFromMemento(mediator.Value.(*Memento)) 92 | } 93 | fmt.Println(text.Read()) 94 | 95 | } -------------------------------------------------------------------------------- /pattern/Observer.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 6 | // 观察者模式(Observer Pattern) 7 | // 定义对象间的一种一对多的依赖关系, 8 | // 当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。 9 | // 10 | 11 | type Observer interface { 12 | Notify(interface{}) 13 | } 14 | 15 | type Subject struct { 16 | observers []Observer 17 | state string 18 | } 19 | 20 | func (s *Subject)SetState(state string) { 21 | s.state = state 22 | s.NotifyAllObservers() 23 | } 24 | func (s *Subject)Attach(observer ... Observer) { 25 | s.observers = append(s.observers, observer ...) 26 | } 27 | 28 | func (s *Subject)NotifyAllObservers() { 29 | for _, obs := range s.observers { 30 | obs.Notify(s) 31 | } 32 | } 33 | 34 | type AObserver struct { 35 | Id string 36 | } 37 | 38 | func (ao *AObserver)Notify(sub interface{}) { 39 | fmt.Println(ao.Id , " receive ", sub.(*Subject).state) 40 | } 41 | 42 | func ObserverTest() { 43 | sub := &Subject{} 44 | a := &AObserver{Id:"A"} 45 | b := &AObserver{Id:"b"} 46 | sub.Attach(a,b) 47 | sub.SetState("hello world") 48 | sub.SetState("i know") 49 | 50 | } -------------------------------------------------------------------------------- /pattern/Prototype.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | // 9 | // 原型模式 10 | // 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 11 | // 12 | // ps:或者可以使用sync.Pool来替代原型模式方式 13 | // 14 | 15 | type Cloneable interface { 16 | Clone() interface{} 17 | } 18 | 19 | type Context struct { 20 | } 21 | 22 | func (this *Context) Clone() interface{} { 23 | new_obj := (*this) 24 | return &new_obj 25 | } 26 | 27 | //结构体基本信息 28 | func (this *Context) string(typ interface{}) (str string) { 29 | v := reflect.ValueOf(typ).Elem() 30 | str += "Type:" + v.Type().Name() + "\n" 31 | for i := 0; i < v.NumField(); i++ { 32 | f := v.Field(i) 33 | str += fmt.Sprintf("index %d: %s %s = %v\n", i, 34 | v.Type().Field(i).Name, f.Type(), f.Interface()) 35 | } 36 | return 37 | } 38 | 39 | type Context1 struct { 40 | Uri string 41 | Context 42 | } 43 | 44 | func (this *Context1) SetUri(uri string) { 45 | this.Uri = uri 46 | } 47 | 48 | func (this *Context1) String() (str string) { 49 | return this.string(this) 50 | } 51 | 52 | type Context2 struct { 53 | Context 54 | Echo string 55 | } 56 | 57 | func (this *Context2) SetEcho(echo string) { 58 | this.Echo = echo 59 | } 60 | 61 | func (this *Context2) String() (str string) { 62 | return this.string(this) 63 | } 64 | 65 | //原型池 66 | type ContextPool map[string]*Context 67 | 68 | func (this *ContextPool) AddContext(key string, val *Context) { 69 | (*this)[key] = val 70 | } 71 | 72 | func (this *ContextPool) GetContext(key string) *Context { 73 | val, ok := (*this)[key] 74 | if ok { 75 | return val.Clone().(*Context) 76 | } 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /pattern/Proxy.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | // 代理模式 9 | // 为其他对象提供一种代理以控制对这个对象的访问 10 | // 优点: 1、职责清晰。 2、高扩展性。 3、智能化。 11 | // 注意事项: 12 | // 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口, 13 | // 而代理模式不能改变所代理类的接口。 14 | // 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式 15 | // 是为了加以控制。 16 | 17 | 18 | // 似乎有点像装饰模式 19 | 20 | type Device interface { 21 | Read()([]byte,error) 22 | Write(word []byte)error 23 | } 24 | 25 | type HardDisk struct { 26 | storage []byte 27 | } 28 | 29 | func(h *HardDisk)Read()([]byte,error){ 30 | return h.storage,nil 31 | } 32 | func(h *HardDisk)Write(word []byte)error{ 33 | h.storage=word 34 | return nil 35 | } 36 | 37 | type HardDiskProxy struct { 38 | OpId string 39 | hd *HardDisk 40 | } 41 | 42 | func(h *HardDiskProxy)Read()([]byte,error){ 43 | if !h.permission("read") { 44 | return nil ,errors.New("You don't have permission to read") 45 | } 46 | return h.hd.Read() 47 | } 48 | func(h *HardDiskProxy)Write(word []byte)error{ 49 | if !h.permission("wrire") { 50 | return errors.New("You don't have permission to write") 51 | } 52 | return h.hd.Write(word) 53 | } 54 | 55 | // 权限判断 56 | func(h *HardDiskProxy)permission(tag string)bool{ 57 | if h.OpId=="admin"{ 58 | return true 59 | } 60 | 61 | if h.OpId=="reader"&&tag=="read"{ 62 | return true 63 | } 64 | 65 | if h.OpId=="writer"&&tag=="wrire"{ 66 | return true 67 | } 68 | 69 | return false 70 | } 71 | 72 | func ProxyTest(){ 73 | var devI Device 74 | devI=&HardDiskProxy{OpId:"admin",hd:&HardDisk{}} 75 | devI.Write([]byte("Hello world!")) 76 | data,_:=devI.Read() 77 | fmt.Println(string(data)) 78 | 79 | devI=&HardDiskProxy{OpId:"reader",hd:&HardDisk{storage:[]byte("only read")}} 80 | err:=devI.Write([]byte("Hello world!")) 81 | fmt.Println(err.Error()) 82 | data,_=devI.Read() 83 | fmt.Println(string(data)) 84 | 85 | devI=&HardDiskProxy{OpId:"writer",hd:&HardDisk{}} 86 | err=devI.Write([]byte("only writer")) 87 | fmt.Println(err) 88 | data,err=devI.Read() 89 | fmt.Println(string(data),err.Error()) 90 | } -------------------------------------------------------------------------------- /pattern/README.md: -------------------------------------------------------------------------------- 1 | # 设计模式 2 | * 创建型 C 3 | * 结构型 J 4 | * 行为型 X 5 | 6 | ``` 7 | -AbstractFactory.go : 抽象工厂模式(C) 8 | -Adapter.go : 适配器模式(J) 9 | -Bridge.go : 桥接模式(J) 10 | -Builder.go : 建造者模式(C) 11 | -ChainOfResponsibility.go : 责任链模式(X) 12 | -Command.go : 命令模式(X) 13 | -Composite.go : 组合模式(J) 14 | -Decorator.go : 装饰器模式(J) 15 | -Facade.go : 外观模式(J) 16 | -Factory.go : 工厂模式(C) 17 | -Flyweight.go : 享元模式(J) 18 | -Interpreter.go : 解释器模式(X) 19 | -Iterator.go : 迭代器模式(X) 20 | -Mediator.go : 中介者模式(X) 21 | -Memento.go : 备忘录模式(X) 22 | -Observer.go : 观察者模式(X) 23 | -Prototype.go : 原型模式(C) 24 | -Proxy.go : 代理模式(J) 25 | -Singleton.go : 单例模式(C) 26 | -Singleton2.go : 单例模式(C) 27 | -State.go : 状态模式(X) 28 | -Strategy.go : 策略模式(X) 29 | -Template.go : 模板模式(X) 30 | -Visitor.go : 访问者模式(X) 31 | ``` 32 | 33 | # 参考资料 34 | * http://www.runoob.com/design-pattern/design-pattern-tutorial.html 35 | * http://www.cnblogs.com/beijiguangyong/archive/2010/11/15/2302807.html#_Toc281750448 36 | * http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html -------------------------------------------------------------------------------- /pattern/Singleton.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | type Singleton interface { 6 | SaySomething() 7 | } 8 | 9 | type singleton struct { 10 | } 11 | 12 | func (singleton) SaySomething() { 13 | fmt.Println("Singleton") 14 | } 15 | 16 | var singletonInstance Singleton 17 | 18 | func NewSingletonInstance() Singleton { 19 | if nil == singletonInstance { 20 | singletonInstance = &singleton{} 21 | } 22 | return singletonInstance 23 | } 24 | -------------------------------------------------------------------------------- /pattern/Singleton2.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | // 4 | //另一种单例模式的实现方式,也是golang语言常用的模式 5 | //采用init()方法全局之实例化一次 6 | // 7 | 8 | import "fmt" 9 | 10 | type Singleton2 interface { 11 | SaySomething() 12 | } 13 | 14 | type singleton2 struct { 15 | } 16 | 17 | func (singleton2) SaySomething() { 18 | fmt.Println("Singleton") 19 | } 20 | 21 | var singletonInstance2 Singleton2 22 | 23 | func init() { 24 | singletonInstance2 = new(singleton2) 25 | } 26 | 27 | func Singleton2SaySomething() { 28 | singletonInstance2.SaySomething() 29 | } 30 | -------------------------------------------------------------------------------- /pattern/State.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 状态模式(State Pattern) 6 | // 核心思想就是:当对象的状态改变时,同时改变其行为,很好理解! 7 | // 就拿QQ来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作, 8 | // 而且你的好友也能看到你的状态, 所以,状态模式就两点: 9 | // 1、可以通过改变状态来获得不同的行为。 10 | // 2、你的好友能同时看到你的变化 11 | 12 | 13 | // 相关模式:命令模式 14 | 15 | // 灯 16 | type Light struct { 17 | State LightState 18 | } 19 | 20 | func(l *Light)PressSwitch(){ 21 | if l.State!=nil { 22 | l.State.PressSwitch(l) 23 | } 24 | } 25 | 26 | // 灯状态 27 | type LightState interface { 28 | PressSwitch(light *Light) 29 | } 30 | 31 | 32 | type OnLightState struct { 33 | 34 | } 35 | 36 | // 开灯 37 | func(ols *OnLightState)PressSwitch(light *Light){ 38 | fmt.Println("turn on light") 39 | // 下一个状态动作为关灯 40 | light.State=&OffLightState{} 41 | } 42 | 43 | type OffLightState struct { 44 | 45 | } 46 | 47 | // 关灯 48 | func(ols *OffLightState)PressSwitch(light *Light){ 49 | fmt.Println("turn off light") 50 | // 下一个状态动作为开灯 51 | light.State=&OnLightState{} 52 | } 53 | 54 | func StateTest(){ 55 | light:=&Light{State:&OnLightState{}} 56 | light.PressSwitch() 57 | light.PressSwitch() 58 | light.PressSwitch() 59 | light.PressSwitch() 60 | } -------------------------------------------------------------------------------- /pattern/Strategy.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // 策略模式(Strategy Pattern) 8 | // 定义一系列的算法,把它们一个个封装起来, 9 | // 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。 10 | 11 | // 相关模式:工厂模式 12 | 13 | type Strategy interface { 14 | Do(interface{}) 15 | } 16 | 17 | // 从A到B 18 | type AToB struct { 19 | // 距离 20 | ABDistance float64 21 | // 到达方式策略 22 | Strategy Strategy 23 | } 24 | 25 | func(ab *AToB) Do(){ 26 | if ab.Strategy!=nil { 27 | ab.Strategy.Do(ab) 28 | } 29 | } 30 | 31 | type BikeStrategy struct { 32 | Speed float64 33 | } 34 | 35 | func(bs *BikeStrategy) Do(ab interface{}){ 36 | aTob,ok:=ab.(*AToB) 37 | if ok &&bs.Speed<=0.0000001{ 38 | return 39 | } 40 | fmt.Println("方式:自行车 用时:",aTob.ABDistance/bs.Speed) 41 | } 42 | 43 | type BusStrategy struct { 44 | Speed float64 45 | } 46 | 47 | func(bs *BusStrategy) Do(ab interface{}){ 48 | aTob,ok:=ab.(*AToB) 49 | if ok &&bs.Speed<=0.0000001{ 50 | return 51 | } 52 | fmt.Println("方式:巴士 用时:",aTob.ABDistance/bs.Speed) 53 | } 54 | 55 | type AirStrategy struct { 56 | Speed float64 57 | } 58 | 59 | func(as *AirStrategy) Do(ab interface{}){ 60 | aTob,ok:=ab.(*AToB) 61 | if ok &&as.Speed<=0.0000001{ 62 | return 63 | } 64 | fmt.Println("方式:飞机 用时:",aTob.ABDistance/as.Speed) 65 | } 66 | 67 | func StrategyTest(){ 68 | aTob:=&AToB{ABDistance:600} 69 | 70 | aTob.Strategy=&BikeStrategy{Speed:15} 71 | aTob.Do() 72 | 73 | aTob.Strategy=&BusStrategy{Speed:90} 74 | aTob.Do() 75 | 76 | aTob.Strategy=&AirStrategy{Speed:500} 77 | aTob.Do() 78 | 79 | } -------------------------------------------------------------------------------- /pattern/Template.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import "fmt" 4 | 5 | // 模板模式(Template Pattern) 6 | // 定义一个操作中算法的框架,而将一些步骤延迟到子类中。 7 | // 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 8 | 9 | type Game interface { 10 | Start() 11 | Playing() 12 | End() 13 | } 14 | 15 | type AbsGame struct { 16 | 17 | } 18 | 19 | func(ag *AbsGame)Start(){ 20 | fmt.Println("start game") 21 | } 22 | func(ag *AbsGame)Playing(){ 23 | fmt.Println("game playing") 24 | } 25 | func(ag *AbsGame)End(){ 26 | fmt.Println("the end") 27 | } 28 | 29 | type FootBall struct { 30 | *AbsGame 31 | } 32 | 33 | func(fb *FootBall)Playing(){ 34 | fmt.Println("playing FootBall") 35 | } 36 | 37 | type Cricket struct { 38 | *AbsGame 39 | } 40 | 41 | func(fb *Cricket )Playing(){ 42 | fmt.Println("playing Cricket ") 43 | } 44 | 45 | func RunGame(g Game){ 46 | g.Start() 47 | g.Playing() 48 | g.End() 49 | } 50 | 51 | func TemplateTest(){ 52 | RunGame(&FootBall{}) 53 | RunGame(&Cricket{}) 54 | } -------------------------------------------------------------------------------- /pattern/Visitor.go: -------------------------------------------------------------------------------- 1 | package pattern 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | // 访问者模式(Visitor Pattern) 主要将数据结构与数据操作分离 9 | // 10 | // 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 11 | // 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。 12 | 13 | 14 | type Visitor interface { 15 | Visit(DataStruct) 16 | } 17 | 18 | type DataStruct interface { 19 | Accept(Visitor) 20 | } 21 | 22 | 23 | type ABData struct { 24 | A int 25 | B int 26 | } 27 | func (as *ABData)Accept(vi Visitor){ 28 | vi.Visit(as) 29 | } 30 | 31 | type AddVisitor struct { 32 | 33 | } 34 | 35 | func (av *AddVisitor)Visit(dataS DataStruct){ 36 | data:=dataS.(*ABData) 37 | sum:=data.A+data.B 38 | fmt.Println("A+B=",sum) 39 | } 40 | 41 | type SubVisitor struct { 42 | 43 | } 44 | 45 | func (sv *SubVisitor)Visit(dataS DataStruct){ 46 | data:=dataS.(*ABData) 47 | sum:=data.A-data.B 48 | fmt.Println("abs(A-B)=",math.Abs(float64(sum))) 49 | } 50 | 51 | func VisitorTest(){ 52 | Data:=&ABData{A:8,B:10} 53 | add:=&AddVisitor{} 54 | sub:=&SubVisitor{} 55 | 56 | Data.Accept(add) 57 | Data.Accept(sub) 58 | } -------------------------------------------------------------------------------- /pattern/doc.go: -------------------------------------------------------------------------------- 1 | // 2 | // 开发模式代码实现包 3 | // # 设计模式 4 | // * 创建型 C 5 | // * 结构型 J 6 | // * 行为型 X 7 | // 8 | // -AbstractFactory.go : 抽象工厂模式(C) 9 | // -Adapter.go : 适配器模式(J) 10 | // -Bridge.go : 桥接模式(J) 11 | // -Builder.go : 建造者模式(C) 12 | // -ChainOfResponsibility.go : 责任链模式(X) 13 | // -Command.go : 命令模式(X) 14 | // -Composite.go : 组合模式(J) 15 | // -Decorator.go : 装饰器模式(J) 16 | // -Facade.go : 外观模式(J) 17 | // -Factory.go : 工厂模式(C) 18 | // -Flyweight.go : 享元模式(J) 19 | // -Interpreter.go : 解释器模式(X) 20 | // -Iterator.go : 迭代器模式(X) 21 | // -Mediator.go : 中介者模式(X) 22 | // -Memento.go : 备忘录模式(X) 23 | // -Observer.go : 观察者模式(X) 24 | // -Prototype.go : 原型模式(C) 25 | // -Proxy.go : 代理模式(J) 26 | // -Singleton.go : 单例模式(C) 27 | // -Singleton2.go : 单例模式(C) 28 | // -State.go : 状态模式(X) 29 | // -Strategy.go : 策略模式(X) 30 | // -Template.go : 模板模式(X) 31 | // -Visitor.go : 访问者模式(X) 32 | // 33 | // 34 | package pattern 35 | --------------------------------------------------------------------------------