gof23结构类模式(golang版)
github欢迎star
https://github.com/transienth...
适配器模式
Adapter模式也被称为Wrapper模式,有以下两种:
类适配器(使用继承)
https://design-
实现目标接口,继承被适配类- 对象适配器(使用委托)
继承目标类,依赖被适配类
参考http://blog.51cto.com/liuxp08...
package main import ( "fmt" ) func main() { duck := &MallardDuck{} turkey := &WildTurkey{} turkeyAdapter := NewTurkeyAdapter(turkey) fmt.Println("The Turkey says...") turkey.gobble() turkey.fly() fmt.Println("The Duck says...") duck.quack() duck.fly() fmt.Println("The Turkey Adapter says...") turkeyAdapter.quack() turkeyAdapter.fly() } type Duck interface { quack() fly() } type Turkey interface { gobble() fly() } type MallardDuck struct { } func (*MallardDuck) quack() { fmt.Println("Quark...") } func (*MallardDuck) fly() { fmt.Println("flying...") } type WildTurkey struct { } func (*WildTurkey) gobble() { fmt.Println("Gobble...") } func (*WildTurkey) fly() { fmt.Println("flying a short distance") } type TurkeyAdapter struct { turkey Turkey } func NewTurkeyAdapter(turkey Turkey) *TurkeyAdapter { return &TurkeyAdapter{turkey} } func (this *TurkeyAdapter) quack() { this.turkey.gobble() } func (this *TurkeyAdapter) fly() { for i := 0; i < 5; i++ { this.turkey.fly() } }
适配器TurkeyAdpater,持有turkey Turkey,实现Duck接口。
代理模式
uml:
https://design-patterns.readt...
代理模式中的成员构成:
- Subject(主体)
- Proxy (代理人)
- RealSubject(实际的主体)
- Client (请求者)
代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目标对象的方法进行拦截和过滤。
golang版的代理模式如下:
Subject
type Git interface { Clone(url string) bool }
RealSubject
type Github struct{} func (p Github) Clone(url string) bool { if strings.HasPrefix(url, "https") { fmt.Println("clone from " + url) return true } fmt.Println("failed to clone from " + url) return false }
Proxy
type GitBash struce { //将持有被代理主体 GitCmd Git } func (p GitBash) Clone(url string) bool { //实际上是被代理主体在执行动作 return p.GitCmd.Clone(url) }
Client
此处client定义为一个coder
type Coder struct {} func (p Coder) GetCode(url string) { gitBash := GetGit() if gitBash.Clone(url) { fmt.Println("success...") } else { fmt.Println("failed...") } } func main() { coder := Coder{} coder.GetCode("https://www.github.com") }
装饰模式
uml
https://design-patterns.readt...
装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活。
装饰模式是代理模式的一种特殊应用,两者的共同点是都具有相同的接口,不同点则是代理模式着重为代理过程的控制,而装饰模式则是对类的功能进行加强或减弱,它着重类的功能变化。
package main import "fmt" type Noddles interface { Description() string Price() float32 } //普通拉面 type Ramen struct { name string price float32 } func (p Ramen) Description() string { return p.name } func (p Ramen) Price() float32 { return p.price } //想吃鸡蛋拉面怎么办? type Egg struct { //多用组合,少用继承,何况golang没有继承 noddles Noddles name string price float32 } func (p Egg) SetNoddles(noddles Noddles) { p.noddles = noddles } func (p Egg) Description() string { return p.noddles.Description() + " + " + p.name } func (p Egg) Price() float32 { return p.noddles.Price() + p.price } //加个香肠吧! type Sausage struct { noddles Noddles name string price float32 } func (p Sausage) SetNoddles(noddles Noddles) { p.noddles = noddles } func (p Sausage) Description() string { return p.noddles.Description() + " + " + p.name } func (p Sausage) Price() float32 { return p.noddles.Price() + p.price } func main() { ramen := Ramen{ name:"ramen", price:8, } egg := Egg{ noddles:ramen, name:"egg", price:2, } egg2 := Egg{ noddles:egg, name:"egg", price:2, } sausage := Sausage{ noddles:egg, name:"sausage", price:2, } fmt.Println("客官,您的普通拉面来了。。。") fmt.Println(ramen.Description()) fmt.Println(ramen.Price()) fmt.Println("客官,您的鸡蛋拉面来了。。。") fmt.Println(egg.Description()) fmt.Println(egg.Price()) fmt.Println("客官,您的双蛋拉面来了。。。") fmt.Println(egg2.Description()) fmt.Println(egg2.Price()) fmt.Println(sausage.Description()) fmt.Println(sausage.Price()) fmt.Println("客官,您的香肠拉面来了。。。") }
外观模式
外观模式也叫做门面模式,要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
uml图
https://design-patterns.readt...
一个服务有若干个子服务,这种情况下,可以引入一个统一的gateway层作为外观模式,统一管理入口。
package main import "fmt" type Facade struct { M Music V Video C Count } func (this *Facade) GetRecommandVideos() error { this.V.GetVideos() return nil } type Video struct { vid int64 } func (this *Video) GetVideos() error { fmt.Println("get videos") return nil } type Music struct { } func (this *Music) GetMusic() error { fmt.Println("get music material") return nil } type Count struct { PraiseCnt int64 CommentCnt int64 CollectCnt int64 } func (this *Count) GetCountById(id int64) (*Count, error) { fmt.Println("get video counts") return this, nil } func main() { f := &Facade{} f.GetRecommandVideos() }
享元模式
package main import ( "fmt" "reflect" ) type Coordinate struct { x, y int } type ChessFlyWeight interface { getColor() string display(c Coordinate) } type ConcreteChess struct { Color string } func (chess ConcreteChess) display(c Coordinate) { fmt.Printf("棋子颜色:%s\n", chess.Color) fmt.Printf("棋子位置:%d----%d\n", c.x, c.y) } func (chess ConcreteChess) getColor() string { return chess.Color } type ChessFlyWeightFactory struct { pool map[string]ChessFlyWeight } func (factory ChessFlyWeightFactory) getChess(color string) ChessFlyWeight { chess := factory.pool[color]; if chess == nil { chess = ConcreteChess{color} factory.pool[color] = chess } return chess } func main() { pool := make(map[string]ChessFlyWeight) factory := ChessFlyWeightFactory{pool } chess1 := factory.getChess("black") chess2 := factory.getChess("black") fmt.Println(reflect.DeepEqual(chess1, chess2)) c1 := Coordinate{1,2} c2 := Coordinate{2, 4} chess1.display(c1) chess1.display(c2) }
桥梁模式
package main import ( "net/http" "fmt" ) //请求接口 type Request interface { HttpRequest() (*http.Request, error) } type Client struct { Client *http.Client } func (c *Client) Query(req Request) (resp *http.Response, err error) { httpReq, _ := req.HttpRequest() resp, err = c.Client.Do(httpReq) return } //实现 type CdnRequest struct { } func (cdn *CdnRequest) HttpRequest() (*http.Request, error) { return http.NewRequest("GET", "/cdn", nil) } //实现2 type LiveRequest struct { } func (cdn *LiveRequest) HttpRequest() (*http.Request, error) { return http.NewRequest("GET", "/live", nil) } func TestBridge() { client := &Client{http.DefaultClient} cdnReq := &CdnRequest{} fmt.Println(client.Query(cdnReq)) liveReq := &LiveRequest{} fmt.Println(client.Query(liveReq)) }
相关推荐
GoatSucker 2020-11-23
CoderToy 2020-11-16
蛰脚踝的天蝎 2020-11-10
ZGCdemo 2020-11-09
86193952 2020-10-27
Lzs 2020-10-23
hjr 2020-10-21
HELLOBOY 2020-10-21
qidiantianxia 2020-10-21
cmsmdn 2020-10-21
myspace 2020-10-21
笑面依旧 2020-10-21
专注前端开发 2020-10-21
技术之博大精深 2020-10-16
zhushenghan 2020-11-09
风雨断肠人 2020-10-13
xuguiyi00 2020-11-04
sichenglain 2020-10-27