github欢迎star

https://github.com/transienth...

适配器模式

Adapter模式也被称为Wrapper模式,有以下两种:

  1. 类适配器(使用继承)

    https://design-
    image
    实现目标接口,继承被适配类
  2. 对象适配器(使用委托)
image
继承目标类,依赖被适配类

参考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...
image

代理模式中的成员构成:

  • 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...
image

装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活。

装饰模式是代理模式的一种特殊应用,两者的共同点是都具有相同的接口,不同点则是代理模式着重为代理过程的控制,而装饰模式则是对类的功能进行加强或减弱,它着重类的功能变化。

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...
image
image

一个服务有若干个子服务,这种情况下,可以引入一个统一的gateway层作为外观模式,统一管理入口。
image

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()
}

享元模式

image

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)
}

桥梁模式

image

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))
}

菟潞寺沙弥
303 声望55 粉丝