Go 代理模式讲解和代码示例

Go 代理模式讲解和代码示例

代理是一种结构型设计模式, 让你能提供真实服务对象的替代品给客户端使用。 代理接收客户端的请求并进行一些处理 (访问控制和缓存等), 然后再将请求传递给服务对象。

代理对象拥有和服务对象相同的接口, 这使得当其被传递给客户端时可与真实对象互换。

概念示例

Nginx 这样的 Web 服务器可充当应用程序服务器的代理:

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

server.go: 主体

package main

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

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
}

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"
}

main.go: 客户端代码

package main

import "fmt"

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

	httpCode, msg = nginxServer.handleRequest(appStatusURL, "GET")
	fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, msg)

	httpCode, msg = nginxServer.handleRequest(appStatusURL, "GET")
	fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, msg)

	httpCode, msg = nginxServer.handleRequest(createuserURL, "POST")
	fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, msg)

	httpCode, msg = nginxServer.handleRequest(createuserURL, "GET")
	fmt.Printf("\nUrl: %s\nHttpCode: %d\nBody: %s\n", appStatusURL, httpCode, msg)
}

output.txt: 执行结果


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
全部评论

相关推荐

白火同学:先说结论,准大三不是特别好找实习,boss沟通300+没有实习是很正常的情况。一是暑期实习时间太短了,二是在这么多准大四都找不到实习,从实习时间和掌握技术层面,企业会优先看他们。 再说简历,其实985本+准大三到这水平的简历也很优秀了,要说的话,项目经历可以再优化一下,可以基本围绕采取STAR原则,分为项目概述、技术架构、技术亮点、实现结果,再发给AI润色一下。 最后说操作,准大三的话,如果想找实习那就多投,不过现在也7月中旬了,时间上已经略晚了。如果7月底实在找不到,也可以多刷点算法,多学点技术,这实习也不至于一定得有,当然有更好。
点赞 评论 收藏
分享
天天困啊:个人建议第一点就是熟悉Redis这里不要这么写,写上Redis比较核心的技术,什么缓存一致性,雪崩穿透击穿那些,掌握cos其实不用写在专业技能里这个你做了鱼皮的这个项目面试官默认应该认为你应该懂了,鱼皮这个项目核心挺多建议多啃啃,在做一个鱼皮的微服务项目俩项目在一起比较好哦
你的简历改到第几版了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务