3

Go でモデルを構築するための慣用的な方法を見つけようとしていますが、大規模なエンタープライズ タイプのアプリのサンプルを見つけるのに苦労しています (たくさんの猫と犬が話すだけです...)。

モデルを使用するための最もクリーンな API を生成するように見えたので、各モデルを個別のパッケージに入れることから始めました。

import "models/person"

person.New(...)     // returns the newly created person
person.GetById(123) // returns a single person
person.GetAll()     // returns a list of people

ただし、その後、モデルが相互にかなり参照する必要があるという問題に遭遇しました。最終的に、次のようなパッケージになりました。

-- File person.go
package Person
import "models/team"

type Person struct {
    Name string
    Team Team
}

func (p *Person) New(...) *Person {
    ...
}

-- File team.go
package Team
import "models/person"

type Team struct {
    Name   string
    People []*Person
}

func (t *Team) New(...) *Team {
    ...
}

循環参照があるため、これは機能しません。API がこのように見えるように、これらすべてのモデルを同じパッケージに追加する必要がありますか?

import "model"

model.NewPerson(...)     // returns the newly created person
model.GetPersonById(123) // returns a single person
model.GetAllPeople()     // returns a list of people

または、これを解決するためにインターフェイスを使用する必要がありますか (もしそうなら、それらはどのように見えますか)?

データベース接続などの処理方法についても質問があります。人々は通常、モデルへのデータベース接続を (直接または何らかの中間オブジェクトを介して) どのように提供しますか? すべての呼び出しは、パラメータとしてデータベースへのインターフェースを取る必要がありますか、それともより良い方法がありますか?

Go で完全な Rest API を構築する大きな例はありますか? ここで 1 つの例を見つけましたが、それはまだかなり小さく、著者は自分が Go の初心者であると述べているため、どれだけ信頼できるかわかりません。

ありがとう!

4

2 に答える 2

0

循環インポートの問題を解決するためだけに、すべてのモデルを 1 つのパッケージにマージする必要はありません。代わりにインターフェースを使用することをお勧めします。

一部の (おそらくリーフ) パッケージは、モデルの動作を定義するインターフェースのみを定義します。注: インターフェイスはデータを定義しません。ただし、ゲッター メソッドとセッター メソッドを介して、任意のデータを動作として抽象化できます。次に、そのインターフェースを満たす任意の数のエンティティを、任意の場所 (個別のパッケージであろうとなかろうと) に配置できます。

このアプローチにより、(おそらくモック化された) モデルのテストも容易になります。

于 2013-09-06T07:41:59.840 に答える