在GO语言中设计MVC架构

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

Designing a MVC architecture in GO

问题

所以,在使用Go设计MVC架构时,我遇到了这个问题。
我在settings模块中创建了一个settings.go文件,其中包含以下内容:

package settings

import (
    _ "github.com/lib/pq"
    "database/sql"
)

func load_db() {
    db, err := sql.Open("postgres", "user=postgres password=postgres dbname=test_db")
}

我的想法是每次API请求到达MVC的视图时都加载这个数据库调用。我在这里面遇到的问题是:

  1. 如何在调用某个控制器类时加载这个函数。
  2. 如何继承db变量以在整个控制器中使用它。

举个Python的例子,我使用一个BaseController来处理这个问题。我在每个地方都继承BaseController,这样就可以创建和关闭db会话。

英文:

So, while designing a MVC architecture in Go, I came across this issue.
I created a settings.go file in settings module which contains this:

package settings

import (
	_ "github.com/lib/pq"
	"database/sql"
)

func load_db() {
	db, err := sql.Open("postgres", "user=postgres password=postgres dbname=test_db")
}

The idea is to load this db call everytime an API request comes in to the views of the MVC. The problem I'm facing here is how do I

  1. Load this function whenever a call to some controller class is done.
  2. Inherit the db variable to use it across the controller.

To give an example in Python, I use a BaseController that deals with this. I inherit the BaseController everywhere and that creates and closes the db session.

答案1

得分: 5

你试图像写Java或Python一样写Go语言。但Go既不是Java也不是Python。Go没有类,而是有类型。Go不使用继承,而是使用组合。

如果你想让某个函数/方法在另一个函数/方法被调用时每次都被调用,你需要显式编写代码:

func (th *BaseThing) Init() {
    th.OpenDB()
    // 在这里编写你的代码。
}

如果你想让多个值共享一个对象,你需要显式设置它:

db := NewDB()
th := NewThing()  // 或者根据你的构造函数设计,使用 th := NewThing(db)
th.DB = db        // 设置共享的对象

如果你想共享这个功能,可以使用组合:

type MyThing struct {
    BaseThing
    // 其他字段在这里。
}

func (th *MyThing) Foo() {
    th.Init() // 相当于 th.BaseThing.Init()。打开数据库等操作。
    // 在这里编写你的代码。
}
英文:

You're trying to write Go like it's Java or Python. Go is neither. Go doesn't have classes, Go has types. Go doesn't use inheritance, Go uses composition.

If you want some function/method to be called every time an another function/method is called, you explicitly code it:

func (th *BaseThing) Init() {
    th.OpenDB()
    // Your code here.
}

If you want multiple values to share a thing, you explicitly set it:

db := NewDB()
th := NewThing()  // Or th := NewThing(db) depending
th.DB = db        // on how you design your constructor.

If you want to share this functionality, use composition:

type MyThing struct {
    BaseThing
    // Other fields here.
}

func (th *MyThing) Foo() {
    th.Init() // Same as th.BaseThing.Init(). Opens DB etc.
    // Your code here.
}

答案2

得分: 3

> 当一个 API 请求进入 MVC 的视图时

在 MVC 架构中,请求被分发给控制器,而不是视图。

> 当对某个控制器类进行调用时,加载这个函数。

在 Go 中,类是被实例化的,而不是被调用的,而且 Go 中没有类的概念。

> 继承 db 变量以在控制器中使用它。

Go 中没有继承的概念。

你正在一个名为 settings 的包中打开一个数据库连接。这可能不是该包的最佳命名。

总的来说,你正在尝试在 Go 中使用 Python/Ruby/PHP 的思维方式。这样做可能不会有很好的效果。请阅读 Go 的文档,并学会像一个 Go 语言开发者一样思考 在GO语言中设计MVC架构

英文:

> an API request comes in to the views of the MVC

In an MVC architecture requests are dispatched to controllers, not views.

> Load this function whenever a call to some controller class is done.

Classes are instantiated, not called and there are no classes in Go.

> Inherit the db variable to use it across the controller.

There's no inheritance in Go.

You're opening a DB connection in a package called settings. This is probably not the best name for that package.

In general, you're trying to do python/ruby/php in Go. That's not gonna get you very far. Read the Go documentation and learn to think like a gopher 在GO语言中设计MVC架构

答案3

得分: 0

我不完全理解你的意思,但是如果你只是想在所有处理程序中共享一个数据库连接,你可以这样做:

var (
    db *sql.DB
)

func main() {
    db = newDb(DbConnection)

    // 这里是处理程序
}


func newDb(connection string) *sql.DB {
    db, err := sql.Open("postgres", connection)
    if err != nil {
        panic(err)
    }

    return db
}

在一个设置文件中,你可以有:

const (
    DbConnection = "user=postgres password=postgres dbname=test_db"
)

所有的处理程序都可以访问到 db 上的连接。SQL 库会自动处理连接池。

英文:

I don't totally understand what you mean but, if you just want to share a db connection to all your handlers you'd do something like this:

var (
        db *sql.DB
)

func main() {
        db = newDb(DbConnection)

        // handlers here
}


func newDb(connection string) *sql.DB {
        db, err := sql.Open("postgres", connection)
        if err != nil {
                panic(err)
        }

        return db
}

and in a settings file you could have:

const (
DbConnection     = "user=postgres password=postgres dbname=test_db"
)

All of your handlers will have access to the connection on db. The sql library handles connection pooling automatically.

huangapple
  • 本文由 发表于 2014年10月8日 19:14:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/26255527.html
匿名

发表评论

匿名网友

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

确定