[go] 代理模式

[go] 代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问

大家好,欢迎来到IT知识分享网。

代理模式

为另一个对象提供一个替身或占位符以控制对这个对象的访问。

模型说明

  • 服务接口(Service Interface)声明了服务接口。代理必须遵循该接口才能伪装成服务对象。
  • 服务(Service)类提供了一些实用的业务逻辑。
  • 代理(Proxy)类包含一个指向服务对象的引用成员变量。代理完成其任务 (例如延迟初始化、 记录日志、 访问控制和缓存等) 后会将请求传递给服务对象。
  • 通常情况下, 代理会对其服务对象的整个生命周期进行管理。
  • 客户端 (Client) 能通过同一接口与服务或代理进行交互, 所以你可在一切需要服务对象的代码中使用代理。

优缺点

1.优点

  • 你可以在客户端毫无察觉的情况下控制服务对象。
  • 如果客户端对服务对象的生命周期没有特殊要求,你可以对生命周期进行管理。
  • 即使服务对象还未准备好或不存在,代理也可以正常工作。
  • 开闭原则: 你可以在不对服务或客户端做出修改的情况下创建新代理。

2.缺点

  • 代码可能会变得复杂,因为需要新建许多类。
  • 服务响应可能会延迟。

使用场景

  • 延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可使用代理模式。
  • 访问控制(保护代理)。如果你只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分,而客户端则是各种已启动的程序(包括恶意程序),此时可使用代理模式。
  • 本地执行远程服务(远程代理)。适用于服务对象位于远程服务器上的情形。
  • 记录日志请求(日志记录代理)。适用于当你需要保存对于服务对象的请求历史记录时。
  • 缓存请求结果(缓存代理)。适用于需要缓存客户请求结果并对缓存生命周期进行管理时,特别是当返回结果的体积非常大时。
  • 智能引用。可在没有客户端使用某个重量级对象时立即销毁该对象。

参考代码

我们用常见的代理中间件 nginx 来做一个例子

  • 提供了对应用程序服务器的受控访问权限。
  • 可限制速度。
  • 可缓存请求。

serverI.go(service 接口)

package main type server interface { 
    handleRequest(string, string) (int, string) } 

application.go(真实的服务)

package main type Application struct { 
    } func (a *Application) handleRequest(url, method string) (int, string) { 
    if url == "/app/status" && method == "GET" { 
    return 200, "Ok" } if url == "/create/user" && method == "POST" { 
    return 201, "User Created" } return 404, "Not Ok" } 

nginx.go(代理)

package main type Nginx struct { 
    application *Application maxAllowedRequest int rateLimiter map[string]int } func newNginxServer() *Nginx { 
    return &Nginx{ 
    application: &Application{ 
   }, maxAllowedRequest: 2, rateLimiter: make(map[string]int), } } func (n *Nginx) handleRequest(url, method string) (int, string) { 
    allowed := n.checkRateLimiting(url) if !allowed { 
    return 403, "Not Allowed" } return n.application.handleRequest(url, method) } func (n *Nginx) checkRateLimiting(url string) bool { 
    if n.rateLimiter[url] == 0 { 
    n.rateLimiter[url] = 1 } if n.rateLimiter[url] > n.maxAllowedRequest { 
    return false } n.rateLimiter[url] = n.rateLimiter[url] + 1 return true } 

main.go(客户端)

package main import "fmt" func main() { 
    nginxServer := newNginxServer() appStatusURL := "/app/status" createuserURL := "/create/user" httpCode, body := nginxServer.handleRequest(appStatusURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(appStatusURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(appStatusURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(createuserURL, "POST") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) httpCode, body = nginxServer.handleRequest(createuserURL, "GET") fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, body) } 

output:

Url: /app/status HttpCode: 200 Body: Ok Url: /app/status HttpCode: 200 Body: Ok Url: /app/status HttpCode: 403 Body: Not Allowed Url: /app/status HttpCode: 201 Body: User Created Url: /app/status HttpCode: 404 Body: Not Ok 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/112375.html

(0)
上一篇 2026-01-18 19:33
下一篇 2026-01-18 20:01

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信