首页 > 解决方案 > OOP MVC 结构通过接口绑定

问题描述

我正在尝试构建具有 OOP 风格的 MVC 框架。我的想法是在路由会话期间绑定控制器和服务,并让功能可以通过接口访问。

当函数触发到服务级别时,我遇到了一个问题,它不断返回“运行时错误:无效的内存地址或 nil 指针取消引用”

路线:

var (
    testService     service.Person             = service.NewPerson()
    testController  controller.TestController  = controller.NewTestController(testService)
)

func RouteHandler(rg *gin.RouterGroup) {
    routes := rg.Group("/api")
    {
        routes .GET("/test", testController.Greet)
    }
}

控制器:

type TestController interface {
    Greet(ctx *gin.Context)
}

type testController struct {
    testService service.Person
}

func NewTestController(testService service.Person) TestController {
    return &testController{
        testService: testService,
    }
}

func (controller *testController) Greet(ctx *gin.Context) {
    res := controller.testService.Greet()
    fmt.Println(res)
    ctx.JSON(http.StatusOK, "test")
}

服务:

type Person interface {
    Greet() string
}

type person struct {
    Person
}

func NewPerson() Person {
    return &person{}
}

func Greet() string {
    return "Hello"
}

标签: oopgo

解决方案


当前person服务嵌入了Person, but NewPersonfactory 方法没有为该Person字段分配任何内容,将其保留为 nil。当Greet在结构上调用方法时person,调用将委托给Personnil 的嵌入式接口,这会导致崩溃。

假设它person是接口的“实现”,Person或者更准确地说,person应该为方法提供与接口定义的相同签名,Person修复可能如下:

type Person interface {
    Greet() string
}

type person struct {
}

func NewPerson() Person {
    return &person{}
}

func (person) Greet() string {
    return "Hello"
}

值得一提的是,Go 中的接口是隐式的。您当前的person声明可能是由于其他语言的习惯,您必须明确指出一个类(在 Go 中没有类)实现了某个接口。


推荐阅读