美文网首页
装饰器模式vs适配器模式 2023-01-10

装饰器模式vs适配器模式 2023-01-10

作者: 9_SooHyun | 来源:发表于2023-01-09 15:03 被阅读0次

    装饰器模式vs适配器模式

    它们都属于【包装模式】

    适配器模式

    适配器的作用就是将一个接口适配到另一个接口,将一类接口转换为另一类接口

    装饰器模式

    pre knowledge:
    函数也是一个对象。而且函数对象可以赋值给变量,所以,通过变量也能调用该函数

    // golang
    myPrint := fmt.Printf
    myPrint("hhh")
    
    // python
    >>> def now():
    ...     print('2015-3-25')
    ...
    >>> f = now
    >>> f()
    2015-3-25
    

    装饰器装饰的对象是函数\方法。函数\方法使用方式不变,但内部功能更加完善
    装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强内部功能

    装饰器的实现和闭包是分不开的

    使用装饰器通常分为2步:实现具体装饰器 + 调用装饰器
    调用装饰器,最简朴的方式就是直接调用该装饰器方法
    另外,不同语言可能对装饰器的调用可能做了语法糖封装。如python调用装饰器,当然可以直接做函数调用,但更常见的是使用@语法糖

    以golang为例,看下装饰器的实现和调用

    // 定义一类装饰器 装饰器不会改变函数签名
    // attention: http.HandlerFunc in, http.HandlerFunc out
    type DecoratorHandler func(http.HandlerFunc) http.HandlerFunc
    
    // 实现一个DecoratorHandler: VerifyHeader. 
    // attention: http.HandlerFunc in, http.HandlerFunc out
    func VerifyHeader(h http.HandlerFunc) http.HandlerFunc {
        return func(w http.ResponseWriter, r *http.Request) {
            token := r.Header.Get("token")
            if token == "" {
                fmt.Fprintf(w,r.URL.Path +" response: Not Logged in")
                return
            }
            // 返回的func引用了入参h,func于是成为闭包
            h(w,r)
        }
    }
    
    
    // use DecoratorHandler to decorate HandlerFunc
    // 实际上decors是通过functional options的方式执行函数调用从而完成装饰的
    func MiddlewareHandlerFunc(hp http.HandlerFunc, decors ...DecoratorHandler) http.HandlerFunc {
        // 注意,需要倒序装饰,不然业务逻辑错乱
        for d := range decors {
            dp := decors[len(decors)-1-d]
            // 直接做最简单的函数调用来完成装饰
            hp = dp(hp)
        }
        return hp
    }
    
    
    func Pong(w http.ResponseWriter, r *http.Request)  {
        fmt.Fprintf(w,r.URL.Path +"response: pong")
        return
    }
    
    
    func main()  {
        http.HandleFunc("/api/asong/ping",MiddlewareHandlerFunc(Pong,VerifyHeader))
        err := http.ListenAndServe(":8080", nil)
        if err != nil {
            log.Fatal("ListenAndServe: ", err)
        }
    }
    

    相关文章

      网友评论

          本文标题:装饰器模式vs适配器模式 2023-01-10

          本文链接:https://www.haomeiwen.com/subject/zvapcdtx.html