为了账号安全,请及时绑定邮箱和手机立即绑定

【学习打卡】第3天 Go设计模式入门到实战

标签:
Go

课程名称:  Go设计模式入门到实践

课程章节:  第5章 结构型模式之装饰模式

主讲老师: Johnny


学习内容:

装饰器模式

概念

        https://img1.sycdn.imooc.com/62eb637e0001595d11060651.jpg

    动态注入行为的设计模式

    对比子类更加灵活,可以对某个对象而不是类造成侵入


步骤及示例

    //定义一个抽象组件

    type Component interface{

        Operate()

    }


    //实现一个具体的组件

    type Component1 struct{}


    func (c1 *Component1)Operate() {
        fmt.Println("c1 operate")

    }


    //定义一个抽象的装饰者

    type Decorator interface{

        Component

        Do() //这是相比于Component组件多出的额外的方法

    }


    //实现一个具体的装饰者

    type Decorator1 struct{

        c Component

    }


    func (d1 *Decorator)Do() {

        fmt.Println("(d1对)c1发生的一个具体的装饰行为")

    }


    func (d1 *Decorator)Operate(){

        d1.Do()

        d1.c.Operate()

    }


    // 使用

    d1 := &Decorator1{}

    c1 := &Component1{}

    d1.c = c1

    d1.Operate()


模拟实战

    https://img3.sycdn.imooc.com/62eb6c1c00019a0412350770.jpg


    实现步骤及示例

    // 实现一个http server

    // 注册一个路由 handler : hello

    // 实现中间件功能: 获取请求方法和URL ; 请求网络地址; 请求响应耗时

    func hello(w http.ResponseWriter, r *http.Request){

        fmt.Fprintf(w, "hello")

    }


    // 实现方式1 耦合版本

    func hello(w http.ResponseWriter, r *http.Request){

        log.Printf("请求方式: %s   URL: %s", r.Method, r.URL)

        log.Printf("请求网络地址: %s", r.RemoteAddr)


        startTime := time.Now()   

        fmt.Printf(w, "hello")

        elapsedTime := time.Since(startTime)

        log.Printf("耗时: %s", elapsedTime)    

    }


    // 实现方式2 装饰者模式(可以有选择的对路由进行装饰)

    func tracing(next http.Handler) http.Handler{

        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){

            log.Printf("请求方式: %s   URL: %s", r.Method, r.URL)

            next.ServeHTTP(w, r)

        })

    }

    

    func logging(next http.Handler) http.Handler{

        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){

            log.Printf("请求方式: %s   URL: %s", r.Method, r.URL)

            next.ServeHTTP(w, r)

        })

    }


    func costing(next http.Handler) http.Handler{

        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){  

                startTime := time.Now()   

                next.ServeHTTP(w, r)

                elapsedTime := time.Since(startTime)

                log.Printf("耗时: %s", elapsedTime)   

        })

    }

    

    

    func main(){

        // 版本1 http.Handle("/", http.HandlerFunc(hello))

        // 装饰者版本

        http.Handle("/", tracing(logging(costing(http.HandlerFunc(hello)))))


        http.ListenAndServe(":8080", nil)

    }


    中间件的注册顺序类似于defer 栈的顺序 LIFO


总结

    https://img1.sycdn.imooc.com/62eb77d20001c1ff12100762.jpg

    https://img3.sycdn.imooc.com/62eb780f0001b61109350328.jpg

    https://img4.sycdn.imooc.com/62eb7848000174aa08980349.jpg

    

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消