Golang没有文件结构吗?

时间:2017-08-05 17:17:37

标签: go

我一直在研究Golang以构建一个Web应用程序,我喜欢语言和所有内容,但是我无法在golang中围绕结构概念进行思考。它似乎迫使我没有文件结构,没有文件夹,没有分区,没有关注点分离。有没有办法以我看不到的方式组织.go文件?到目前为止,文件结构一直很令人头痛,这是我用这种语言唯一的糟糕体验。谢谢!

2 个答案:

答案 0 :(得分:2)

你是部分正确的。 Go不强制执行有关文件和包结构的任何内容,除非它禁止循环依赖。恕我直言,这是一件好事,因为你有自由选择最适合你的套房。

然而,它决定什么是最好的,这给你带来了负担。我尝试了很少的方法,取决于我在做什么(例如库,命令行工具,服务),我相信不同的方法是最好的。

如果您只创建命令行工具,请让root软件包(存储库的根目录)为main。如果它是小工具,那就是你所需要的。您可能会发生命令行工具增长,因此您可能希望将某些内容分离到自己的内容中,但可以在同一个存储库中进行分配。

如果您要创建库,请执行相同的操作,但包名称将是您的库的名称,而不是main

如果你需要组合(这对于库和命令行工具都很有用),我会在VCS根目录中放入库代码(库的所有内容),以及潜在的子包和{{1}为你的二进制文件。

对于网络服务,我发现遵循these指南是最实际的。最好阅读整篇博文,但简而言之 - 在VCS root中定义您的域,创建cmd/toolname(或多个)作为命令行入口点,并为每个依赖项创建一个包(例如memcache,database,http等) )。您的子包从不明确地相互依赖,它们只共享来自root的域定义。它需要一些习惯,我仍然适应我的用例,但到目前为止看起来很有希望。

答案 1 :(得分:1)

正如@ del-boy所说,这取决于你想做什么,我多次讨论这个问题,但是在开发golang web应用程序时,更适合我的是按照依赖项划分你的包

- myproject 
-- cmd 
--- main.go
-- http
--- http.go
-- postgres
--- postgres.go
-- mongodb
--- mongodb.go
myproject.go

myproject.go 将包含接口 Structs ,其中包含主域名或商业模式

例如,你可以在 myproject.go

里面
type User struct {
MongoID    bson.ObjectId `bson:"_id,omitempty"`
PostgresID string
Username       string 
}

和这样的界面

type UserService interface { 
GetUser(username string) (*User, error)
}

现在,在 http 包中,您将处理公开api端点

 //Handler represents an HTTP API interface for our app.
type Handler struct {
    Router         *chi.Mux // you can use whatever router you like
    UserService    myproject.UserService
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *Request){
//this just a wrapper for the Router ServeHTTP
h.Router.ServeHTTP(w,r)
}

func (h *Handler) someHandler(w http.ResponseWriter, r *Request){
//get the username from the request
// 
user := h.UserService.GetUser(username)
}

在postgres.go中,您可以使用结构来实现 UserService

type PostgresUserService struct {
DB *sql.DB
}

然后实现服务

func (s *PostgresUserService) GetUser(username string) {
//implement the method
}

和mongodb可以做同样的事情

type MongoUserService struct {
Session *mgo.Session
}

func (s *MongoUserService) GetUser(username string) {
    //implement the method
    }

现在你的cmd / main.go中你可以有类似的东西

func main(){
postgresDB, err := postgres.Connect()
mongoSession, err := mongo.Connect()

postgresService := postgres.PostgresUserService{DB: postgresDB}
mongoService := mongo.MongoUserService{Session: mongoSession}

//then pass your services to your http handler
// based on the underlying service your api will act based on the underlying service you passed 
myHandler := http.Handler{}
myHandler.UserService = postgresService


}

假设你更改了底层商店,你只需要在这里更改它,你就不会改变任何东西

这个设计受到了blog的启发,我希望你觉得它很有用