【Go 精选】设计模式 - 代理、适配器和装饰器模式

2023-04-16  本文已影响0人  熊本极客

1.代理模式

代码

package proxy

type Subject interface {
    Do() string
}

type RealSubject struct{}

func (RealSubject) Do() string {
    return "real"
}

type Proxy struct {
    real RealSubject
}

func (p *Proxy) Do() string {
    var res string

    // 在调用真实对象之前的工作,检查缓存,判断权限,实例化真实对象等。。
    res += "pre:"

    // 调用真实对象
    res += p.real.Do()

    // 调用之后的操作,如缓存结果,对结果进行处理等。。
    res += ":after"

    return res
}

测试用例

package proxy

import "testing"

func TestProxy(t *testing.T) {
    var sub Subject
    sub = &Proxy{}

    res := sub.Do()

    if res != "pre:real:after" {
        t.Fail()
    }
}

// === RUN   TestProxy
// --- PASS: TestProxy (0.00s)
// PASS

2.适配器模式

代码

package adapter

//Target 是适配的目标接口
type Target interface {
    Request() string
}

//Adaptee 是被适配的目标接口
type Adaptee interface {
    SpecificRequest() string
}

//AdapteeImpl 是被适配的目标类
type adapteeImpl struct{}

//SpecificRequest 是目标类的一个方法
func (*adapteeImpl) SpecificRequest() string {
    return "adaptee method"
}

//NewAdaptee 是被适配接口的工厂函数
func NewAdaptee() Adaptee {
    return &adapteeImpl{}
}

//Adapter 是转换Adaptee为Target接口的适配器
type adapter struct {
    adaptee Adaptee
}

//Request 实现Target接口
func (a *adapter) Request() string {
    return a.adaptee.SpecificRequest()
}

//NewAdapter 是Adapter的工厂函数
func NewAdapter(adaptee Adaptee) Target {
    return &adapter{adaptee}
}

测试用例

package adapter

import "testing"

var expect = "adaptee method"

func TestAdapter(t *testing.T) {
    adaptee := NewAdaptee()
    target := NewAdapter(adaptee)
    res := target.Request()
    if res != expect {
        t.Fatalf("expect: %s, actual: %s", expect, res)
    }
}

// === RUN   TestAdapter
// --- PASS: TestAdapter (0.00s)
// PASS

3.装饰器模式

代码

package decorator

type Component interface {
    Calc() int
}

type ConcreteComponent struct{}

func (*ConcreteComponent) Calc() int {
    return 0
}

type MulDecorator struct {
    Component
    num int
}

func (d *MulDecorator) Calc() int {
    return d.Component.Calc() * d.num
}

func WarpMulDecorator(c Component, num int) Component {
    return &MulDecorator{
        Component: c,
        num:       num,
    }
}

type AddDecorator struct {
    Component
    num int
}

func (d *AddDecorator) Calc() int {
    return d.Component.Calc() + d.num
}

func WarpAddDecorator(c Component, num int) Component {
    return &AddDecorator{Component: c, num: num}
}

测试用例

package decorator

import "fmt"

func ExampleDecorator() {
    var c Component = &ConcreteComponent{}
    c = WarpAddDecorator(c, 10)
    c = WarpMulDecorator(c, 8)
    res := c.Calc()

    fmt.Printf("res %d\n", res)
}
上一篇 下一篇

猜你喜欢

热点阅读