国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > php教程 > 设计模式-代理模式(Go语言描述)

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

来源:程序员人生   发布时间:2016-06-16 09:10:56 阅读次数:2048次

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

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

模式定义

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

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

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

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

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

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

代码演示

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

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

type Git interface { Clone(url string) bool }

ok, 很简单, 只有1个Clone方法,表示我们要从git源来clone项目。 下面我们接着来实现1下真实对象, 也就是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方法中的逻辑, 我们就不用关心了, 还有1个重要的角色我们还没看, 来看看代理怎样写吧。

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

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

还剩下最后1个角色, 那就是我们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方法。 最后我们再来看看运行结果。

完善, 现在理解甚么是代理模式了吧。代理模式其实最主要的用处就是当我们没法直接访问1个对象的时候, 通过代理的方式来完成对对象的访问。代理模式具有高扩大性,假设我们需要从GitLab上,只需要提供者添加1个GitLab对象, 然后我们调用GetGit时指定使用GitLab就能够了。

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

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

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生