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

习惯研究所所长 · · 4195 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、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语言 有趣的接口

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4195 次点击  
加入收藏 微博
下一篇:Go性能调优
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传