go - GO 中的开放式设计和可扩展性

标签 go struct interface abstraction

我尝试在 go 中实现某种具有可扩展性的开放式设计范例,但想知道这样做的 gopher 方法是什么。

例如我有一个车辆包。根据可用的实现方式,我想创建一个包含所有可能车辆的数组。在这个例子中,如果只有自行车可用,我想要一个数组 [bike] 如果还有另一个汽车实现,我想要 [bike,car]

我真的不知道如何在 go 中执行此操作。我想到了车辆包中的接口(interface),但我真的不知道如何根据可用的包创建数组。这应该是开放式设计,这样如果有人决定编写另一辆车,一辆卡车,即它会自动在上游工作。

所以这是解释问题的一些示例代码: 如果没有必要,它们被分成包,它们也可以在同一个包(车辆)中

车辆.go

package vehicle

type vehicle interface {
    drive() string
}

自行车.go

package bike

type bike struct {
    name string
}

func (b *bike) drive() string {
    return "drive bike drive"
}

func NewVehicle() bike {
    return &bike{
        name: "bike",
    }
}

汽车.go

package car

type carstruct {
    name string
}

func (b *car) drive() string {
    return "drive cardrive"
}

func NewVehicle() car{
    return &car{
        name: "car",
    }
}

最佳答案

我会认为 imagedatabase/sql 的设计以及它们如何与其他库合作更加惯用,但是如果你真的需要实现这种设计,我想出了一些 hack-y 的东西。

诀窍是,golang 可以在全局变量声明期间进行函数调用,并且发生在调用任何 init 之前。所以我们可以在那期间做注册工作。

//vehicle.go
import (
    "fmt"
)

var _ = register("3",4)

type constructor func() *Vehicle

var reg = make(map[string]consturctor)

func register(name string, cons) bool {
    _,ok:=reg[name]
    if ok {
        return false
    }
    reg[name] = cons
    return true
}

var chosen string

func init() {
    //turn that map into a slice if you want
    //Chose one "implentation" from the slice/map if you wish
    for chosen = range reg {
        break // Take the first, it is dirty, I know.
    }
    if Chosen=="" {
        panic("No Implentation!")
    }
}

func NewVehicle() *Vehicle {
    return reg[chosen]() 
}

func main() {
    fmt.Println("Hello, playground")
}

//car.go

var carsucc = register("car",constructor(NewCar))

func init() {
    if !carsucc {
        panic("car: multiple implentation!")
    }
    //off course you can fail silently
}

func NewCar() Vehicle {
    return &Car{}
}

关于go - GO 中的开放式设计和可扩展性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48338704/

相关文章:

unit-testing - 测试非不透明错误值

objective-c - 如何在 XCode(Swift 或 Obj-C)中记录结构内的结构

java - 使用 instanceof 测试接口(interface)

java - 通过匿名类

go - 如何在 Go 中解析日历周数

go - 序列化结构以通过 UDP 发送它

function - 从函数返回函数以及为什么省略括号?

c - 在 C 中使用可变长度数组初始化结构

c++ - 为什么使用reinterpret_cast 将char* 转换为结构似乎可以正常工作?

objective-c - 如果@protected 是默认值,为什么这个ivar 需要@protected?