当前位置: 首页 > news >正文

ucenter使用自己做的网站免费域名解析

ucenter使用自己做的网站,免费域名解析,vs做网站mvc,口碑好的网站开发前言 我一直以来对golang的装饰器模式情有独衷,不是因为它酷,而是它带给我了太多的好处。首先我不想说太多的概念,熟记这些概念对我的编程来说一点用处没有。我只知道它给我带来了好处,下面谈谈我的理解。 这种模式可以很轻松地…

前言

我一直以来对golang的装饰器模式情有独衷,不是因为它酷,而是它带给我了太多的好处。首先我不想说太多的概念,熟记这些概念对我的编程来说一点用处没有。我只知道它给我带来了好处,下面谈谈我的理解。

这种模式可以很轻松地把一些函数装配到另外一些函数上,让你的代码更加简单,也可以让一些“小功能型”的代码复用性更高,让代码中的函数可以像乐高玩具那样自由地拼装。

重要的是你不用修改代码以前的功能,对以前的功能没有影响,而是动态的,很方便的扩展函数的功能。下面我将举几个例子说明下

golang 的装饰器通常用interface{} 以及 anonymous functions 实现的,下面我们看看实际的例子

一、interface{} 实现装饰器

type Printer interface {Print() string
}
​
type SimplePrinter struct {}
​
func (sp *SimplePrinter) Print() string {return "Hello, world!"
}
​
func BoldDecorator(p Printer) Printer {return PrinterFunc(func() string {return "<b>" + p.Print() + "</b>"})
}
​
type PrinterFunc func() string
​
func (pf PrinterFunc) Print() string {return pf()
}
​
func main() {simplePrinter := &SimplePrinter{}boldPrinter := BoldDecorator(simplePrinter)fmt.Println(simplePrinter.Print()) // Output: Hello, world!fmt.Println(boldPrinter.Print()) // Output: <b>Hello, world!</b>
}
  1. 在上面的代码中我们定义了一个Printer接口,一个 SimplePrinter 结构体实现了Print方法

  2. 我们定义了 BoldDecorator 函数接受一个Printer接口返回一个Printer接口.该函数将原来的 Print() 方法封装到一个新的方法中,该方法返回的是用 <b> 标记括起来的相同值

  3. 这只是一个简单的例子,却展示了装饰器的强大的功能。通过添加新的装饰器,我们可以在运行时改变对象的行为,而无需更改其原始代码。当我们需要为一个已经存在的对象添加新功能,而又想保持其原始代码不变时,装饰器模式就显得尤为有用。这样,我们就可以避免为每一个想要添加的新功能创建新的子类。

二、Http 相关的装饰器的例子

func WithServerHeader(h http.HandlerFunc) http.HandlerFunc {return func(writer http.ResponseWriter, request *http.Request) {writer.Header().Set("server", "0.01")h(writer, request)}
}
​
func withServerSetCook(h http.HandlerFunc) http.HandlerFunc {return func(writer http.ResponseWriter, request *http.Request) {cookie := http.Cookie{Name: "username", Value: "tt"}http.SetCookie(writer, &cookie)h(writer, request)}
}
​
func WithBasicAuth(h http.HandlerFunc) http.HandlerFunc {return func(writer http.ResponseWriter, request *http.Request) {cookie, err := request.Cookie("username")if err != nil || cookie.Value != "ee" {writer.WriteHeader(http.StatusForbidden)return}h(writer, request)}
}
​
func WithDebugLog(h http.HandlerFunc) http.HandlerFunc {return func(writer http.ResponseWriter, request *http.Request) {request.ParseForm()log.Println(request.Form)log.Println("path", request.URL.Path)log.Println("Host", request.URL.Host)log.Println(request.Form["url_long"])for k, v := range request.Form {log.Println("key:", k)log.Println("value:", v)}h(writer, request)}
}
​
func hello(w http.ResponseWriter, r *http.Request) {log.Printf("Recieved Request %s from %s\n", r.URL.Path, r.RemoteAddr)fmt.Fprintf(w, "Hello, World! "+r.URL.Path)
}
​
func main() {http.HandleFunc("/hello/v1", WithServerHeader(hello))http.HandleFunc("/hello/v2", withServerSetCook(hello))http.HandleFunc("/hello/v3", WithBasicAuth(hello))http.HandleFunc("/hello/v4", WithDebugLog(hello))err := http.ListenAndServe(":8080", nil)if err != nil {log.Fatal("ListenAndServe: ", err)}
}
  1. 例子中 WithServerHeader,withServerSetCook,WithBasicAuth, WithDebugLog 就是一个装饰器,它传入一个 http.HandlerFunc 就是一个改写版本。而我们的业务hello不用修改任何功能,可以呈现出一些新的功能,很多人把这种模式称为middleware ,我更喜欢称为装饰器

三、多个装饰器Pipeline,也是options 模式

type googleSlide struct {sreSlide *list.Listinterval int64mutex    sync.Mutexk        int64
}type slideVal struct {time   int64req    int64accept int64
}type SlideValOptions func(val *slideVal)func NewSlideval(options ...SlideValOptions) *slideVal {t := &slideVal{time: time.Now().UnixNano(),}for _, option := range options {option(t)}return t
}func WithReqOption(req int64) SlideValOptions {return func(val *slideVal) {val.req = req}
}func WithAcceptReqOption(accept int64) SlideValOptions {return func(val *slideVal) {val.accept = accept}
}func NewGoogleSlide(interval time.Duration, k int64) *googleSlide {return &googleSlide{sreSlide: list.New(),interval: interval.Nanoseconds(),k:        k,}
}func (g *googleSlide) Sre() grpc.UnaryClientInterceptor {return func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {g.mutex.Lock()now := time.Now().UnixNano()front := g.sreSlide.Front()for front != nil && front.Value.(*slideVal).time+g.interval < now {g.sreSlide.Remove(front)front = g.sreSlide.Front()}var r, accept int64front = g.sreSlide.Front()for front != nil {t := front.Value.(*slideVal)r += t.reqaccept += t.acceptfront = front.Next()}tail := (float64(r) - float64(g.k*accept)) / (float64(r) + 1)if tail > 0 {g.mutex.Unlock()return errors.New("request is fail")}g.sreSlide.PushBack(NewSlideval(WithReqOption(1)))err := invoker(ctx, method, req, req, cc, opts...)if err == nil {g.sreSlide.PushBack(NewSlideval(WithAcceptReqOption(1)))}g.mutex.Unlock()return err}
}

这个代码是我在SRE 熔断器写的代码,现在重新拿出来,是因为具有代表性 。NewSlideval 可以支持多个装饰器,遍历装饰器,就可以得倒我们想要的功能,只要我们去实现这个装饰器。这样的代码,在golang 是常用的,在初始化配置函数经常用

http://www.hkea.cn/news/205843/

相关文章:

  • wordpress后台加统计代码seo建站的步骤
  • 怎么做外贸网站的邮箱签名搜索引擎优化是指什么
  • 网页制作基础教程免费邯郸网站seo
  • phpcms做网站感想漯河seo推广
  • 公司部门kpi绩效考核指标模板河北百度seo软件
  • 印团网网站是哪家做的唯尚广告联盟
  • 网红营销网站seo综合查询怎么用的
  • 西安地区网站建设云推广
  • wordpress个人站2020年关键词排名
  • 网站建设企业公司石家庄新闻头条新闻最新今天
  • 道滘镇做网站百度统计
  • qq空间做宣传网站怎样建立自己的网站平台
  • 做设计一般用的素材网站是什么意思刷网站排名软件
  • 帮人做兼职的网站吗青岛seo服务哪家好
  • 贷款类网站怎样做网络营销的推广
  • 乐清做网站哪家好税收大数据
  • 校园网站建设需求天津放心站内优化seo
  • 哈尔滨微网站建设热搜在哪里可以看
  • 网站用oracle做数据库福州seo推广服务
  • 康保县城乡建设委员会网站营销型网站重要特点是
  • 手机做网站的步骤跨境电商有哪些平台
  • 请人做网站要多少网络事件营销
  • 网站页脚有什么作用厦门seo哪家强
  • 东莞百度提升优化优化推广网站推荐
  • 查企业网站有哪些站长统计app软件
  • 做a高清视频在线观看网站济源新站seo关键词排名推广
  • 刚做的网站怎么搜索不出来百度seo收录软件
  • 视频拍摄app站长工具seo综合查询广告
  • 新闻单位建设网站的意义武汉seo推广优化
  • 低价网站公司软文怎么写