Golang设计模式-代理模式

一.介绍

意图:为其他对象提供一种代理以控制对这个对象的访问。

主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

何时使用:想在访问一个类时做一些控制。

如何解决:增加中间层。

关键代码:实现与被代理类组合。

应用实例: 1、Windows 里面的快捷方式。 2、猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。 3、买火车票不一定在火车站买,也可以去代售点。 4、一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。 5、spring aop。

二.类图

三.代码 

实现代码:

package Proxy

import (
	"errors"
	"sync"
	)

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

type RealRequest struct {}
func (request *RealRequest) handleRequest(url string, method string) (int, error) {
	if url == "WIkipedia.org" && method == "post" {
		return 200, nil
	}
	return 404, errors.New("not find, 404")
}


type ngx_http_proxy_module struct {
	request *RealRequest
	maxRequestNum int
	handleRequestMap map[string]int
}

var instance *ngx_http_proxy_module
var once sync.Once
func GetNgxProxyInstance(maxRequestNum int) *ngx_http_proxy_module{
	once.Do(func() {
		instance = &ngx_http_proxy_module{
			request : &RealRequest{},
			maxRequestNum: maxRequestNum,
			handleRequestMap:make(map[string]int, 0),
		}
	})
	return instance
}

func (nginx *ngx_http_proxy_module) check(url string) error {
	if _, ok := nginx.handleRequestMap[url]; !ok {
		return nil
	}
	if nginx.handleRequestMap[url] >= nginx.maxRequestNum {
		return errors.New("the num of request more than limit")
	}
	return nil
}
func (nginx *ngx_http_proxy_module) addRequstCount(url string) {
	nginx.handleRequestMap[url] = nginx.handleRequestMap[url] + 1
}

func (nginx *ngx_http_proxy_module) HandleRequest(url string, method string) (int, error)  {
	if err := nginx.check(url); err != nil {
		return 403, err
	}
	nginx.addRequstCount(url)
	return nginx.request.handleRequest(url, method)
}


测试:

package main

import (
"./Proxy"
	"fmt"
)

func main() {
	nginx := Proxy.GetNgxProxyInstance(3)
	url1 := "baidu.com"
	url2 := "google.com"
	fmt.Println(nginx.HandleRequest(url1, "get"))
	fmt.Println(nginx.HandleRequest(url1, "post"))
	fmt.Println(nginx.HandleRequest(url2, "post"))
	fmt.Println(nginx.HandleRequest(url2, "post"))


	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest(url2, "post"))
	return
}

测试结果:

package main

import (
"./Proxy"
	"fmt"
)

func main() {
	nginx := Proxy.GetNgxProxyInstance(3)
	url1 := "baidu.com"
	url2 := "google.com"
	fmt.Println(nginx.HandleRequest(url1, "get"))
	fmt.Println(nginx.HandleRequest(url1, "post"))
	fmt.Println(nginx.HandleRequest(url2, "post"))
	fmt.Println(nginx.HandleRequest(url2, "post"))


	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest("WIkipedia.org", "post"))
	fmt.Println(nginx.HandleRequest(url2, "post"))
	return
}

四.优点缺点

  • 优点: 
  1. 职责清晰。
  2. 高扩展性。
  3. 智能化。
  • 缺点: 
  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

五.使用场景

  1.  远程代理。
  2. 虚拟代理。
  3. Copy-on-Write 代理。
  4. 保护(Protect or Access)代理。
  5. Cache代理。
  6. 防火墙(Firewall)代理。
  7. 同步化(Synchronization)代理。
  8. 智能引用(Smart Reference)代理。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是几种常见的Golang设计模式: 1. 工厂模式(Factory Pattern):用于创建对象的模式,通过定义一个创建对象的接口来实现对象的实例化。 ```go type Shape interface { Draw() } type Circle struct{} func (c *Circle) Draw() { fmt.Println("Drawing a circle") } type Rectangle struct{} func (r *Rectangle) Draw() { fmt.Println("Drawing a rectangle") } type ShapeFactory struct{} func (sf *ShapeFactory) GetShape(shapeType string) Shape { if shapeType == "circle" { return &Circle{} } else if shapeType == "rectangle" { return &Rectangle{} } return nil } func main() { factory := &ShapeFactory{} circle := factory.GetShape("circle") circle.Draw() // 输出:Drawing a circle rectangle := factory.GetShape("rectangle") rectangle.Draw() // 输出:Drawing a rectangle } ``` 2. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。 ```go type Singleton struct{} var instance *Singleton func GetInstance() *Singleton { if instance == nil { instance = &Singleton{} } return instance } func main() { singleton1 := GetInstance() singleton2 := GetInstance() fmt.Println(singleton1 == singleton2) // 输出:true } ``` 3. 观察者模式(Observer Pattern):定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。 ```go type Subject struct { observers []Observer } func (s *Subject) Attach(observer Observer) { s.observers = append(s.observers, observer) } func (s *Subject) Notify() { for _, observer := range s.observers { observer.Update() } } type Observer interface { Update() } type ConcreteObserver struct{} func (co *ConcreteObserver) Update() { fmt.Println("Observer is updated") } func main() { subject := &Subject{} observer := &ConcreteObserver{} subject.Attach(observer) subject.Notify() // 输出:Observer is updated } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值