用string创建一个struct的实例

时间:2014-07-16 08:17:18

标签: go

我正在构建一个应用程序,我想在其中使用一个简单的mvc模型

我有一个包控制器,里面有像这样的控制器结构

type UserController struct {}

func (u *UserController) Index(res http.ResponseWriter, req http.Request) {
  // some code in it
}

我想要实现的是我可以通过像

这样的字符串来创建该控制器的实例
func NewAppController("user") { }

所以我可以通过路线请求动态创建我的控制器实例

我想到的另一种方式是像这样映射我的控制器

var controllerProvider = map[string]interface{} {
   "user": &controllers.UserController{},
   "warehouse": &controllers.WarehouseController{},
 }

然后通过

调用它
appController = mux.Vars(req)["controller"]
c := controllerProvider[appController]

但我宁愿用第一种方式知道如何处理这个问题?

2 个答案:

答案 0 :(得分:2)

您可以尝试创建一个实现reflect.Type接口的新对象,然后通过reflect的机制使用它,但这看起来完全是浪费时间。相反,请考虑以下替代方案:

  • 使用Name stringMethods map[string]ActionFunc等字段制作结构。这可行,但对我来说看起来并不是很惯用。 (如果有的话,这会让人想起一些JavaScript OOP实现。)

  • 使用框架。如果您对MVC感到满意,为什么不使用已存在的Go的MVC框架之一?想到了Beego和Revel。

  • 完全反思您的架构。从我现在看到的,你正在尝试编写Go,就像它的Ruby-on-Rails一样。去是不同的。从vanilla net/http开始,创建应用的最小实现。那是你的原型。有了这个原型,你可以重写它并扩展它。想要足智多谋的路线?添加gorilla/mux或其他选择的路由器。需要数据存储吗?添加ORM。想要更多的可测试性和灵活性?接口,接口无处不在。

答案 1 :(得分:0)

如果您使用此:

var controllerProvider = map[string]interface{} {
   "user": &controllers.UserController{},
   "warehouse": &controllers.WarehouseController{},
}

请注意,这些不是每次访问的新实例。如果多次使用controllerProvider,它将始终返回指向仅在那里初始化的实例的指针。

您可能希望使用函数动态生成实例:

var controllerProvider = map[string]func() interface{}{
    "user":      func() interface{} { return &controllers.UserController{} },
    "warehouse": func() interface{} { return &controllers.WarehouseController{} },
}

c := controllerProvider[appController]()