美文网首页
19年第34周:Go语言 有趣的接口

19年第34周:Go语言 有趣的接口

作者: 习惯研究所所长 | 来源:发表于2019-08-24 14:19 被阅读0次

    一、Golang的接口

    • Go语言接口设计很符合设计原则


      参考图灵丛书中的《设计模式》

    当我看到Golang的接口时,让我想起来在《设计模式》的开篇部分关于“针对接口编程”的内容。
    废话不多说,来体会一下“针对接口编程”如何通过组合来实现代码的复用?

    二、设计一个模拟鸭子的应用程序

    ①程序结构

    实现鸭子的行为

    ②程序代码

    • main.go
    package main
    import (
        "fmt"
        "./models"
    )
    func main() {
        // 1, 实例化一只周黑鸭
        zbDuck := models.ZhouBlackDuck{}
        // 2, 实例化一只小黄鸭
        yDuck := models.ZhouBlackDuck{}
    
        // 3, 鸭子们,请开始你们的表演
        fmt.Println("各位观众注意,鸭子们要开始表演了!")
        // -报上名来
        zbDuck.Show()
        yDuck.Show()
        // -开始飞吧
        zbDuck.Fly()
        yDuck.Fly()
        // -叫一个
        zbDuck.Quack()
        yDuck.Quack()
    
    }
    
    • myDuck.go
    package models
    
    import "fmt"
    
    /*
        一个超类型,多个接口;
        一个接口,多种方法;
        一个具体的类型:通过组合具有不同方法的类型而实现复用;
     */
    
    // 1, 定义抽象类型:鸭子Duck 超类型
    type Duck struct {
    
    }
    func (d *Duck) Show(){
        fmt.Println("我是鸭子,所有的继承我的,都是鸭子!")
    }
    
    // 2, 定义一个接口:飞行行为FlyBehavior接口
    type FlyBehavior interface {
        Fly()  // 我专门搞飞行的,无需管你是鸭子还是人
    }
    
    // 3, 定义一个接口:呱呱叫行为QuackBehavior接口
    type QuackBehavior interface {
        Quack() // 我专门负责呱呱叫的,无需管你是鸭子还是人
    }
    
    // 4, 定义类型:飞行行为接口的各种飞行行为
    
    // 4.1 飞行方式1:用翅膀飞
    type FlyWithWings struct{
        // 实现一种飞行方式的类型
    }
    func (fww *FlyWithWings) Fly(){
        // 用翅膀飞
        fmt.Println("用翅膀飞的具体实现")
    }
    
    // 4.2 飞行方式2:不会飞的飞行
    type FlyNoWay struct {
        // 实现一种飞行方式的类型
    }
    func (fnw *FlyNoWay) Fly(){
        // 不会飞的那种飞
        fmt.Println("不会飞的那种飞的具体实现")
    }
    
    // 5, 定义类型:呱呱叫行为接口的各种呱呱叫行为
    type RealQuack struct {
        // 实现一种呱呱叫的类型
    }
    func (q *RealQuack)Quack(){
        // 很纯的那种叫
        fmt.Println("很纯的那种叫的具体实现")
    }
    type SQuack struct {
        // 实现一种呱呱叫的类型
    }
    func (sq *SQuack)Quack(){
        // 吱吱叫的那种叫
        fmt.Println("吱吱叫的那种叫的具体实现")
    }
    type QuackNoWay struct {
        // 不会叫的那种叫
    }
    func (qnw *QuackNoWay)Quack(){
        // 不会叫的那种叫
        fmt.Println("不会叫的那种叫的具体实现")
    }
    
    // 具体的鸭子类型,不用重写飞行和叫的方法,而只需要组合即可
    
    // 6, 具体的鸭子:周黑鸭
    type ZhouBlackDuck struct {
        // 我想要一只周黑鸭,它能够飞,也会叫
        // 1, 组合超类型
        Duck // 通过组合超类型(本质还是普通类型)鸭子来继承
        // 2, 组合飞的类型:实现了飞的方法
        FlyWithWings // 飞呀飞呀那个飞呀
        // 3, 组合叫的类型:
        RealQuack //
    }
    // 6, 具体的鸭子:小黄鸭
    type YellowDuck struct {
        // 我需要一只小黄鸭:它不能飞,但会吱吱叫
        // 1, 组合超类型
        Duck
        // 2, 组合飞的类型
        FlyNoWay // 不会飞也是鸭子啊
        // 3, 组合叫的类型
        SQuack // 不会呱呱叫,但我会吱吱叫
    } 
    

    三、好处在哪里?

    问题

    问: 如果鸭子只有2种行为,行为A和行为B,行为A有M种,行为B有N种。

    • ①采用继承的方式,需要编写多少个鸭子类才能完全覆盖所有的鸭子类型?

    每一个鸭子类需要重写父类的鸭子叫,鸭子飞

    # 超类鸭子
    class Duck(object):
        def Show(self):
            pass
    
        def Quack(self):
            # // 鸭子叫,由之类实现
            pass
    
        def Fly(self):
            # // 鸭子飞,由之类实现
            pass
    
    class Duck1(Duck):
        # // 重写父类的鸭子叫,鸭子飞
        pass
    
    class Duck2(Duck):
        # // 重写父类的鸭子叫,鸭子飞
        pass
    class Duck3(Duck):
        # // 重写父类的鸭子叫,鸭子飞
        pass
    
    class DuckMN(Duck):
        # // 第M*N个鸭子类
        pass
    
    • ②采用组合的方式 ,又是多少呢?
      组合仅仅只需要组合,而无需自己实现
    搭积木的组合方式

    等用继承的方式写完,大概,就会发现,代码全是鸭子!

    小黄鸭呀小黄鸭,不知道我说得够不够明白,你懂没呢

    相关文章

      网友评论

          本文标题:19年第34周:Go语言 有趣的接口

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