使用Golang继承来实现类似Backbone的集合/模型。

huangapple go评论87阅读模式
英文:

golang inheritance to implement backbone like collection / model

问题

我正在研究使用Go语言作为我的Web后端的首选语言。我目前使用的语言是PHP,在那里我实现了一个类似于Backbone Collection/Model结构的数据结构。

关于Collection / Model

这意味着我有一个包含多个模型(Models)的集合(Collection)。模型(Models)有一个属性字典(attributes)用于存储实际的“公共数据”。集合(Collections)有多个方便的方法来操作模型(Models)数组(排序、按索引获取、按匹配参数获取等等)。模型(Models)也有它们自己的方便方法。

在日常生活中,有90%的“事物”以相同的方式表示。例如,我可以以相同的方式存储一个“地址”和存储我的“用户”。有一个包含我的“地址”(Addresses)的“地址集合”(AddressesCollection),我可以简单地要求我的“地址集合”给我所有“城市为柏林”的“地址模型”(AddressModels)。通过在我的基类中实现这个匹配,我可以在我的“用户集合”(UserCollection)上做同样的逻辑操作,给我所有被“deactivated=true”停用的用户。

但有时候(10%)我需要一个特殊的方法。例如,对于“地址”(Addresses)来说,我需要一个“getGeoData”方法。现在,在我的面向对象的世界中,我可以简单地创建一个扩展我的“BaseModel”的新类,添加我的方法,并在我的基类使用的地方使用我的扩展类。

我“简直不明白”

在Go中如何实现这个呢?我读了很多关于嵌入/组合的介绍,但我简直无法理解。

这就是我的困惑,记住这只是我学习“继承”概念的游乐场,而不是为了拥有一个可用于生产的Collection / Model实现。

GoPlayground

我明白的是,我还没有“理解”如何编写一个接受不完全继承类型的“通用”方法。我有一种感觉,我必须在某个地方使用接口来获得这种“继承”/“扩展类”的感觉。但是我目前对此的使用...嗯...

但也许我在以这种方式实现我期望的结构的概念上完全错了?也许有一种更加优雅的方式。任何提示都将不胜感激!

英文:

I am looking into golang as my new goto language for my web-backend. My current language there is PHP, where I implemented a datastructure resembling the Backbone Collection/Model structure.

excursus Collection / Model

This means I have a Collection containing multiple Models. Models have an attributes dictionary for storing the actual "public data". Collections have multiple convenience methods operating on the array of Models (sort, getByIndex, getByMatchingParameter, etc). Models also have their share of convenience methods.

In daily life there will be 90% of "things" that are represented the same way. For example I can store an Address the same way I store my User. Having an AddressesCollection containing my Addresses I can simply ask my AddressesCollection to give me all AddressModels where city=Berlin. And implementing this matching in my base class I can do the logically same thing on my UserCollection giving me all my Users which are deactivated by deactivated=true.

But sometimes (10%) I need a special method. getGeoData for Addresses for example. Now, in my oop-world, I can simply create a new class extending my BaseModel adding my method and use my extended class everywhere where my base class was used.

My "i simply don't get it"

How does this work in Go. I read a lot introductions into embedding / composition. But simply do not get my head around this.

This is where I stand, keep in mind this is my playground for learning the "inheritance" concept, not for having a production ready Collection / Model implementation.

GoPlayground

What I get is that I haven't "understood" how to write a "generic" method accepting not-quite-inherited types. I have the feeling that I have to use an interface there somewhere to get this "inheritance"/"extended class" feeling. But my current use of this is... well...

But maybe I am completely wrong in my concept of implementing my desired structure that way in go at all? Maybe there is a much more elegant way. Any hints greatly appreciated!

答案1

得分: 1

你离正确的理解很接近,但是你把多个不同的东西混淆了。

完整的示例:https://play.golang.org/p/wpj82QRVUP

  1. 类型嵌入

你有两个模型 UserAddress,它们都共享一些公共字段,可能还有方法。这是创建一个共同的结构体 Model 的好理由,如上面的链接所示。所有三个结构体都是不同类型

  1. 集合

你可以有一个接口的集合或者定义类型的集合。那么什么时候使用哪个呢?

如果你有一个地址的集合,定义类型如下:
type AddrCollection []*Address。然后在 AddrCollection 类型上实现任何你想要的方法。

如果你有一个模型的集合,类似地定义 type ModelCollection []*Model,但是将 Address 传递给 ModelCollection 需要"提取"嵌入类型。

如果你有一个东西的集合,那么定义一个接口的集合(示例中的 DescriberCollection),但是在其中不会有 GetByAddress() 方法,它只会存在于 AddrCollection 中。

  1. 接口

接口没有字段,它们只定义要实现的方法签名。在 Go 中,接口通常被接受而不是返回,这使得你可以拥有清晰和目标明确的设计。接口是一种允许其他用户(或其他包)以不需要实现你的类型,而只需要实现某些方法的方式来使用你的包/库的方法。他们可以重用你定义的类型,或者他们可以插入自己的接口实现。那么接口是什么呢?它是一种说法的方式:这里是一组方法签名,只要你实现它们,你就可以使用我的包

英文:

You are pretty close to getting it right, but you have mixed up multiple different things.

Complete example: https://play.golang.org/p/wpj82QRVUP

  1. Type embedding

So you have two models User, Address and they both share common fields and maybe methods. This is a good reason to create a common struct for both: Model, as shown in the link above. All three structs are of different types.

  1. Collections

You can have a collection of interfaces or collection of defined types. So when to use which?

If you have a collection of addresses, defined the type of follows:
type AddrCollection []*Address. And then implement whatever method you want on AddrCollection type.

If you have a collection of models, similarly define type ModelCollection []*Model, but then passing Address to the ModelCollection would require to "extract" the embedded type.

If you have a collection of something, then define a collection of interfaces (DescriberCollection in the example), but then you would not have GetByAddress() defined on it, and it would only exist in AddrCollection

  1. Interfaces

They have no fields they only define method signatures to be implemented. In Go interfaces are normally accepted and never returned, that gives u a benefit to have clean and goal-oriented design. Interfaces is a way to allow other users (or other packages) to use your packages/libraries in a way that they do not need to implement your types, but rather a certain methods. They can reuse your defined types, or they can plug-in their own implementations of the interface. So what is an interface, it is a way of saying: here are the set of method signatures, as long as you implement them you can use my package

答案2

得分: 0

好的,以下是翻译好的内容:

好的,看起来我确实没有理解这个问题的Go方式。

帮助我继续前进的关键词有:

  • ORM(对象关系映射)
  • go generate

看起来可以解决我的问题的项目有:

无论如何,感谢你的回答!

英文:

Ok, looks like I really didn't understand the go-way of doing this.

The buzzwords that helped me to move on:

  • ORM
  • go generate

Projects that look like solving my issue:

Thanks for the answers, anyway!

huangapple
  • 本文由 发表于 2017年6月10日 15:36:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/44470806.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定