go语言设计模式

本文探讨了Go语言中的两种设计模式——适配器模式和代理模式。适配器模式用于为对象添加特定功能,而代理模式则侧重于控制对对象的访问,可以在运行时动态构建。在代理模式中,代理类通常在编译时就与真实对象建立关系,而在装饰器模式中,原始对象是在运行时传递给装饰者的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:适配器模式

package adapter

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

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

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

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

//NewAdapter 是Adapter的工厂函数
func NewAdapter(adaptee Adaptee) Target {
	return &adapter{
		Adaptee: adaptee,
	}
}
//Adapter 是转换Adaptee为Target接口的适配器
type adapter struct {
	Adaptee
}

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


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

*/

二:代理模式和装饰模式

这两个方法都能给对象增加一些特定的功能。

对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个 接口。对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。此外,不论我们使用哪一个模式,都可以很容易地在真实对象的方法前面或者后面加上自定义的方法。

        然而,实际上,在装饰器模式和代理模式之间还是有很多差别的。装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话 说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。

        我们可以用另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。实现上就是是否把一个对象作为参数传递的区别!

    来看代理模式

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

装饰器模式,主要多了一个New方法包装了一下!

package main
// 装饰器模式,主要是用到了组合的思想
import (
    "time"
    "fmt"
)
//定义基本组件
type LogDecorate interface {
    Info() string
}
// 定义基本对象
type LogBody struct {
    Msg string
}

func (this LogBody) Info() string {
    return this.Msg
}

type LogTimeField struct {
    dec LogDecorate
}

func (this *LogTimeField) Info() string {
    return time.Now().Format("[2006-1-2 15:04:05]") + this.dec.Info()
}

func NewLogTimeField(decorate LogDecorate)*LogTimeField{
    return &LogTimeField{decorate}
}
// 定义装饰对象
type LogNameField struct {
    dec  LogDecorate
    name string
}

func (this *LogNameField) Info() string {
    return this.name + ":" + this.dec.Info()
}

func NewLogNameField(name string,decorate LogDecorate)*LogNameField{
    return &LogNameField{decorate,name}
}

func Log(msg string,name string){
    var log LogDecorate
    log  = LogBody{msg}
    log  = NewLogTimeField(log)
    if name!=""{
        log = NewLogNameField(name,log)
    }
    fmt.Println(log.Info())
}
 
func main() {
	Log("zhao","mmm")
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值