golang设计模式(7)代理模式

15 篇文章 0 订阅
10 篇文章 1 订阅

代理模式作用
代理模式为其他对象提供一种代理以控制对一个对象的访问。是一种对象结构型模式。

代理模式适用性
在需要用比较通用和复杂的对象指针代替简单的指针的时候,适用代理模式,下面为适用代理模式的常见情况:
1)远程代理(Remote Proxy):为一个对象在不同的地址空间提供局部代表。
2)虚代理:根据需要常见开销很大的对象
3)保护代理(Protection Proxy):控制对原对象的访问,保护代理用于对象应该有不同的访问权限的时候。
4)智能引用:取代了简单的指针,它在访问对象时执行一些附加操作,经典用途包括:
.指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它。
.当第一次引用一个持久对象时,将它装入内存。
.在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

结构(uml)
代理模式uml

代理模式的效果
代理模式在访问对象时引入了一定程度的间接性。根据代理的类型,附加的间接性有多种用途:
1)Remote Proxy可以隐藏一个对象存在于不同地址空间的事实。
2)virtual Proxy可以进行最优化,例如根据需要创建对象。
3)Protection Proxy和Smart Reference都允许在访问一个对象时有一些附加的事务处理(Housekeeping task)。
代理模式还可以对用户隐藏另外一种称为copy-on-write的优化方式(linux内核中大量使用),这种优化和根据需要创建对象有关。拷贝一个庞大而复杂的对象是一种开销很大的操作,如果这个拷贝根本就没有被修改,那么这开销就没有必要。用代理延迟这一拷贝过程,我们可以保证只有当这个对象被修改的时候才对它进行拷贝。

golang实现
综上所述,代理模式可以有很多不同的表示,这里先对第三种进行实现:

package main

import (
    "fmt"
)

type Handler interface {
    HandleData(string) (interface{}, error)
}

type DBHandler struct {
    DBname string
}

func (pD *DBHandler) HandleData(data string) (interface{}, error) {
    fmt.Println("Get Db data by query sql :", data)
    return nil, nil
}

type AppHandler struct {
    Handler *DBHandler 
}

func (pA *AppHandler) HandleData(data string) (interface{}, error) {
    if true { //Get Data from redis ok
        fmt.Println("Get Data from redis")
    } else {
        pA.Handler.HandleData(data)
        //store ret data data to redis 
    }
    return nil, nil
}

func main() {

    var iHandler Handler
    iHandler = &AppHandler{Handler: &DBHandler{DBname: "mysql"}}
    iHandler.HandleData("username")
    return
}

输出结果为:

Get Data from redis

从实例可以看出,在AppHandler中增加了优化查询逻辑,当redis中无对应数据时才到mysql中查询数据。这就对DBHandler 的访问进行可控制。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值