英文:
Go - how to organize code for dynamic packages
问题
我有一个用Go语言编写的小型Web应用程序。它是一个更大系统的基础,我希望它可以扩展,可以添加/删除组件,而不需要修改基础部分。
目前的结构如下:
App
Modules
Core
... 这里是核心文件 ...
app.go
main.go
app.go将包含一个路由方法,根据请求路径确定哪个模块负责处理请求。每个模块/组件都有自己的控制器。
每个组件都有自己的包名,所以我认为这是不可能的,因为Go语言要求显式导入。
例如,我可以添加一个名为"blog"的新模块/组件,如下所示:
App
Modules
Core
... 这里是核心文件 ...
controller.go
Blog
... 这里是博客文件 ...
controller.go
app.go
main.go
英文:
I have a small web application written in Go. It is created a base for a larger system and I would like it to be extendable where components can be added/removed without needing this base to be modified in any way.
The structure is currently:
App
Modules
Core
... Core Files Here ...
app.go
main.go
app.go will contain a routing method which should take a web request and based on the request path know which module is responsible for handling the request. Each module/component having its on controller.
Each component will have its own package name so i think this is going to be impossible since go forces an explicit import.
For example i may add a new module/component called say blog such as:
App
Modules
Core
... Core Files Here ...
controller.go
Blog
... Blog Files Here ...
controller.go
app.go
main.go
答案1
得分: 3
有几种方法可以实现你的目标。由于Go目前不支持动态加载库,所以当你添加或删除任何组件时,可能需要重新编译你的应用程序。因此,最简单的方法是创建一个yourapp/core
包,其中包含以下内容:
- 一个
Application
类型,具有作为主应用程序的ServeHTTP
方法 - 一个
Component
接口,所有组件都必须实现该接口。你可能还想在接口中包含一个BaseUrl() string
和一个ServeHTTP
方法。 - 一个
Register
方法,用于向Application
类型添加新组件。
然后,你可以在单独的包中实现你的组件(例如yourapp/blog
),它们可能依赖于你的yourapp/core
包。
唯一仍然需要"用户可编辑"的是main.go
文件,它可能如下所示:
func main() {
app := core.NewApplication()
app.Register(blog.Blog{
Title: "My Personal Blog",
})
app.Register(...)
app.Run()
}
另一种方法可能是为你的组件定义一个RPC接口(可能包括RegisterComponent
、UnregisterComponent
和GetGlobalConfig
等函数)。
然后,你可以在单独的进程中运行这些组件,这样做的好处是你可以动态地启动/停止/重新加载这些组件,而它们不会破坏你的主应用程序。如果你想使用这种方法,可以查看一下net/rpc包,甚至可能还有httputil.NewSingleHostReverseProxy。
英文:
There are several ways to achieve your goal. Since Go does not support dynamically loaded libraries at the moment, you need to probably recompile your application whenever you add/remove any components. The simplest way therefore would be a yourapp/core
package with the following:
- an
Application
type with anServeHTTP
method that acts as your main application - a
Component
interface that all your components have to implement. Your might want include aBaseUrl() string
and aServeHTTP
method there. - a
Register
method to yourApplication
type, that can be used to add new components to your app.
Your components can then be implemented in separate packages (e.g. yourapp/blog
) and they will probably depend on your yourapp/core
package.
The only thing that still needs to be "user-editable" is the main.go
file, which might look like this:
func main() {
app := core.NewApplication()
app.Register(blog.Blog{
Title: "My Personal Blog",
})
app.Register(...)
app.Run()
}
Another approach might be to define an RPC interface for your components (which might include functions like RegisterComponent
, UnregisterComponent
and a GetGlobalConfig
).
Then, you can run those components in separate processes which has the advantage that you can start/stop/reload those components dynamically and they can not break your main app. Take a look at the net/rpc package and maybe even httputil.NewSingleHostReverseProxy if you want to use this approach instead.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论