关闭

设计模式-代理模式(Go语言描述)

标签: go语言设计模式
5962人阅读 评论(0) 收藏 举报
分类:

大家好, 我是大帅哥,由于最近又变帅了, 所以我决定由我的代理人小帅哥来写这篇博客,不过内容可以放心,还是由我来完成,小帅哥的活就是将我的内容替我发出来罢了。

&_& 还是进入正题吧, 今天这篇博客我们继续来学习设计模式, 在学习了上面几个设计模式之后大家有没有发现设计模式其实很简单, 难道地方是何时选用合适的模式, 这也是设计模式最重要的地方, 不能我们学会的设计模式就可以乱用。 明白就好…… 下面我们就开始介绍一个新的设计模式-代理模式

模式定义

什么是代码模式? 其实文章刚开始的段子并不是寻开心的,其实那就是现实生活中的一个代理模式, 你和我之前通过一个中间人来完成通讯, 其实就这么简单。 虽然简单, 我们还是有必要来看一下人家总结的定义:

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

怎么理解呢? 网上有一个段子解释的很好, 比如你喜欢一个妹子, 不好意思跟人家开口, 这时候你可能就通过她舍友来表达你的爱慕了。 再来看看代理模式的类图吧,通常情况下, 看完定义迷迷糊糊的, 看完类图可能就糊糊的, 等看完代码示例, 就彻底明白了。

从图中可以看到, 代理模式共有4个角色, 其中一个还是抽象的。

  1. Client 就是上面那个段子中的你, 你是行为的主导者。
  2. Subject 是代理人和被代理的抽象接口
  3. RealSubject 被代理的对象, 也就是上面的妹子
  4. Proxy 代理者, 对应上面的妹子室友

不过, 仔细看看类图, 我开始怀疑代理模式的必要性了。 有必要吗? 我直接去调用RealSubject不就行了, 还这么麻烦, 通过一个代理来调用, 这不就是脱了裤子放屁吗? 其实不然, 很多情况下, 真实的对象是我们访问不到的,或者是提供者不想让我们访问到, 这个时候我们就需要一个代理来帮我们完成。举个例子? 很简单, 我们访问一个网站, 数据是不是都放数据库里? 但是网站的提供这不允许我们直接操作数据库, 这个时候就提供了一个页面, 我们通过页面来间接的往数据库里插入数据。

代码演示

好了, 文字的东西不多扯了, 下面我们就用代码来演示一下吧, 在今天我代码中, 我们来模拟一下平时我们使用github的过程,我们在从github上clone项目的时候一般都是通过命令行来完成吧, 其实这个命令行完全可以看作是github的一个代理。

根据上面的类图, 我们首先要提供一个抽象的接口来规范代理和对象的行为

type Git interface {
    Clone(url string) bool
}

ok, 很简单, 只有一个Clone方法,表示我们要从git源来clone项目。 下面我们接着来实现一下真实对象, 也就是Github

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
}

GitHub实现了Clone方法, 所以它实现了Git接口,至于Clone方法中的逻辑, 我们就不用关心了, 还有一个重要的角色我们还没看, 来看看代理怎么写吧。

type GitBash struct {
    Gitcmd Git
}

func (p GitBash) Clone(url string) bool {
    return p.Gitcmd.Clone(url)
}

这是我们的命令行, 它持有一个Git类型的变量, 并且他还是先了Clone方法, 我们在调用Clone方法的时候,其实是间接的调用了这个Git类型变量的Clone方法,这就是代理!

还剩下最后一个角色, 那就是我们Coder自己了, 我们自己就随意多了

type Coder struct{}

func (p Coder) GetCode(url string) {
    gitBash := GetGit(1)
    if gitBash.Clone(url) {
        fmt.Println("success")
    } else {
        fmt.Println("failed")
    }
}

GetGit是啥? 其实就是提供者提供给我们的可调用的接口。

func GetGit(t int) Git {
    if t == 1 {
        return GitBash{Gitcmd: GitHub{}}
    }

    return nil // 可能还有其他的git源
}

首先,我们知道我们是要从GitHub上clone项目, 所以我们告诉代理要从GitHub上给我clone项目,别跑GitLab上去了。接下来我们就调用代理的Clone方法,通过前面的代码我们完全可以理解,这里面肯定是调用了GitHubClone方法。 最后我们再来看看运行结果。

完美, 现在理解什么是代理模式了吧。代理模式其实最主要的用途就是当我们无法直接访问一个对象的时候, 通过代理的方式来完成对对象的访问。代理模式具有高扩展性,假如我们需要从GitLab上,只需要提供者添加一个GitLab对象, 然后我们调用GetGit时指定使用GitLab就可以了。

今天的博客很简单,其实模式的代码都是很简单的,不要被设计模式这四个字吓到。 我们6月份再见!

代码放github上了,欢迎star: https://github.com/qibin0506/go-designpattern

1
0
查看评论

go语言: 设计模式-代理模式(Go语言描述)

go语言: 设计模式-代理模式(Go语言描述) 深入Django ORM的继承关系 java: [HackerRank] Diagonal Difference Go: Go语法规范点 golang: GOLANG 中HTTP包默认路由匹配规则阅读笔记 ...
  • daisongwan
  • daisongwan
  • 2016-05-31 10:13
  • 175

设计模式-策略模式(Go语言描述)

好久没有更新博客了,最近也是在忙着充电,从今天这篇博客开始,我们来了解一下设计模式。设计模式那什么是设计模式呢?首先来看看我从百科上copy下来的概念吧。 设计模式/软件设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了...
  • qibin0506
  • qibin0506
  • 2016-01-22 23:49
  • 6541

各用一句话描述23种设计模式

Abstract Factory(抽象工厂):提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。Adapter(适配器):将一个类的接口转换成调用者希望的另外一个接口。适配器模式是的原本由于接口不兼容而不能在一起工作的那些类可以一起工作。Bridge(桥接):将抽象部分与他的实现...
  • hayre
  • hayre
  • 2016-09-06 16:09
  • 994

go语言实现设计模式(二):简易工厂

简易工厂主要是用来解决对象“创建”的问题。以下的例子取自《大话设计模式》中第一章,实现一个可扩展的“计算器”。当增加新的功能时,并不需改动原来已经实现的算法。由于是简易工厂,所以我们还是需要对工厂类进行相应修改。1.首先,我们定义一个计算的接口package calctype CalcSuper i...
  • yzh900927
  • yzh900927
  • 2015-11-01 10:29
  • 859

【设计模式】代理模式详解

前言 博主只是一名大三学生,文章内容难免有不足之处,欢迎批评指正。   正文 转载请注明出处: http://blog.csdn.net/h28496/article/details/46707621 发 表 时 间: 2015年7月1日   什么是代理模式? 为其他对象提供一种...
  • H28496
  • H28496
  • 2015-07-01 10:45
  • 1381

设计模式:代理模式(Proxy)

代理模式:为其他对象提供一种代理以控制对这个对象的访问。 代理模式中的角色: 抽象主题角色(Subject):声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。 具体主题角色(RealSubject):也称为委托角色或者被代理角色。定义了代理对象所代表的目...
  • u013256816
  • u013256816
  • 2016-03-29 21:38
  • 4399

设计模式(结构型)之代理模式(Proxy Pattern)

代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理、远程代理、虚拟代理、缓冲代理等,它们应用于...
  • yanbober
  • yanbober
  • 2015-05-04 18:48
  • 5695

23种设计模式(6):代理模式

先看一个例子,是有关于打游戏杀怪兽的。 //先定义一个游戏者接口 public interface IGamePlayer { //登陆游戏 public void login(String user, String password); //杀怪,网络游戏的主要角色 ...
  • psp0001060
  • psp0001060
  • 2016-02-04 22:05
  • 939

六 设计模式之代理模式(或称委托模式)

<br />定义   为其它对象提供一种代理以控制对这个对象的访问<br />类图<br /><br /><br /><br /><br /><br />通用代码 抽象主题类 pu...
  • guojun828
  • guojun828
  • 2011-01-20 23:26
  • 7166

最常用的设计模式---代理模式(C++实现)

代理模式:为其他对象提供一种代理以控制对这个对象的访问
  • lh844386434
  • lh844386434
  • 2014-01-09 17:23
  • 2056
    个人资料
    • 访问:662392次
    • 积分:6963
    • 等级:
    • 排名:第3948名
    • 原创:80篇
    • 转载:0篇
    • 译文:2篇
    • 评论:629条
    文章分类
    博客专栏
    友情链接

    鸿洋_

    Aggie的博客

    梁肖技术中心

    极客导航

    最新评论