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