gof23结构类模式(golang版)

五月花号区块链联盟 · · 854 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

适配器模式

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

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

https://design-

image

实现目标接口,继承被适配类

  1. 对象适配器(使用委托)
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

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:五月花号区块链联盟

查看原文:gof23结构类模式(golang版)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

854 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传