質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

意見交換

クローズ

2回答

470閲覧

golangのモデリングについて

tomoharu

総合スコア107

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

2クリップ

投稿2023/02/06 04:59

0

2

テーマ、知りたいこと

当方、RubyとJavaScriptで仕事をしていますが、趣味でGolangを書いているものです。
golangにはstructというものがありますが、"text/template"モジュールを使う際に、全く別の概念を一つのstructに格納してしまうのではと思ったためご相談です。以下に詳細書きます。

背景、状況

一つのhtmlの画面で複数のループを行いたい場合、text/template(もしくはhtml/template)を使って以下のように書くことができます。

go

1package main 2 3import ( 4 "html/template" 5 "log" 6 "os" 7) 8 9var tmplSrc = ` 10Slice One: 11{{ range .SliceOne }} 12 {{ . }} 13{{ end }} 14 15Slice Two: 16{{ range .SliceTwo}} 17 {{ . }} 18{{ end }}` 19 20type Data struct { 21 SliceOne []int 22 SliceTwo []string 23} 24 25func main() { 26 t := template.Must(template.New("tmpl").Parse(tmplSrc)) 27 28 data := &Data{ 29 []int{1, 2, 3}, 30 []string{"one", "two", "three"}, 31 } 32 33 if err := t.Execute(os.Stdout, data); err != nil { 34 log.Fatalln(err) 35 } 36}

この例の場合は特にstruct内のsliceoneなどには意味を持たせていないので問題ないかもしれませんが、実際には一つの画面で複数の別の概念をループさせたい場合などあるかと思います。
例えば、本を投稿して一覧で閲覧できるアプリがあったとして、
「実際に投稿した本の一覧」

「ユーザーが投稿成功した際に画面に描画するメッセージ」
が考えられると思います。

両方とも複数個描画させたい場合、上記のコードと同じように書くと、

go

1type Data struct { 2 Books []Book 3 Notifications []Notification 4}

となるかと思います。
このような書き方だと、BookとNotificationの抽象概念がDataというものとなってしまい、モデリングとして正しいのか?と疑問に思ってしまいました。そもそもこのBookとNotificationを同じstructに格納するべきなのかと思っています。なぜなら、そんなことを言ってしまったらこの世の全てのオブジェクトはDataのstructに格納できてしまい、godclass(golangにはclassはないですが)のようなものが生まれてしまうからです。実際にはそうしないとコードが動かないのでそうしていますが。。。ただおそらくオブジェクト指向の考えで上記のような考えになっている気もしていて、golangはオブジェクト指向の言語ではないという話を聞いたことがあるので、考え方の違いなんだろうかとも思っています。

以上質問内容としましては、

・複数のオブジェクトループを実現するより良いコードはありますか?
・もしない場合、上の書き方はモデリング(DataがBooksとNotificationsの抽象概念になってしまっていること)として正しいのでしょうか?
・そもそもgolangではそのような考え方はしないのでしょうか?

何卒よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

回答2

#1

nobonobo

総合スコア3367

投稿2023/02/06 05:54

dataはあくまで「テンプレートに渡すデータ」という解釈で作るもので、
必ずしも構造体定義をPublicに行う必要はありません。

以下のようにmap型で都度組み上げるのもアリだと思います。

go

1data := map[string]interface{}{ 2 "SliceOne": []int{1, 2, 3}, 3 "SliceTwo": []string{"one", "two", "three"}, 4}

また、コンテンツとエラー情報を渡すという定型を見出して以下の様な構造体を定義するのもアリかと。

go

1type Data struct { 2 Content interface{} 3 Notifications: []Notification 4}

Contentには[]Booksなどの値を入れるだけで済みます。
(もちろんテンプレートを書く人はContentに何の型データが入っているのかは把握して書く必要があります)

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#2

tomoharu

総合スコア107

投稿2023/02/06 09:57

ご連絡ありがとうございます。

コンテンツとエラー情報を渡すという定型を見出して以下の様な構造体を定義するのもアリかと。

こちら良いなと思いました。

「テンプレートに渡すデータ」という解釈で作るもので、

結局解釈の問題になって結構難しいなと思いましたが、こちらも結構納得できました。
ありがとうございます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

最新の回答から1ヶ月経過したため この意見交換はクローズされました

意見をやりとりしたい話題がある場合は質問してみましょう!

質問する

関連した質問