1

I understand that Go is not an object-oriented language but I'm trying to implement a inheritance structure in my Iris controllers as suggested by this article. My main motivation for doing so is to avoid repetition. So far, it has been working for me. Take a look at the following code for example.

// APIController.go (package Controllers)
type APIController struct {
    mvc.C
}
func (c *APIController) Post(data map[string][]string) ([]byte, error) {
    data_parsed := c.ParseFormData(data)
    return json.Marshal(data_parsed)
}

// UserController.go  (package Controllers)
type UserController struct {
    mvc.C
    *APIController
}

func (c *UserController) Post() ([]byte, error) {
    return c.APIController.Post(c.Ctx.FormValues())
}

So far so good.

But I'm finding it difficult to replicate the same strategy for Models. This is what I've done so far

// Model.go (package Models)
type Model struct {
    Id         string `json:"_id"`
    Created_at string `json:"created_at"`
    Updated_at string `json:"updated_at"`
    Deleted_at string `json:"deleted_at"`
}
// implements further set of functions to be used by 'child' models...

// User.go (package Models)
type User struct {
    *Model

    First_name string `json:"first_name"`
    Last_name  string `json:"last_name"`
    Email      string `json:"email"`
    Username   string `json:"username"`
    Password   string `json:"password"`
    Last_login string `json:"last_login"`
}


// APIController.go (package Controllers)
type APIController struct {
    mvc.C
    Model Models.Model
}

// UserController.go  (package Controllers)
type UserController struct {
    mvc.C
    *APIController
}

func (c *UserController) Post() ([]byte, error) {
    c.APIController.Model = new(Models.User) //WRONG!
    return c.APIController.Post(c.Ctx.FormValues())
}

As you can see, the APIController is expecting type Models.Model while UserController is passing *Models.User. The end goal is to have a generic model in APIController that any model from any controller and then is able to call all the functions defined in Models.Model so that I don't have to call those function everywhere.

Is it possible to do so? If not, what might be the best approach to avoid repeating the code?

Update

By using inheritance and single parent model and using that in parent APIController, I want to avoid replicating my filter/CRUD logic. For example, inside UserController, if I want to save a record, then instead of using User.Save(input_data) inside UserController, the Save should ideally be defined inside Models.Model and from APIController, I'm able to call Model.Save(input_data) rather than making the same call from child controllers individually.

4

1 回答 1

1

首先制作Model一个接口而不是一个结构。让它包含所有模型应该通用的所有方法:

type Model interface {
    // Common methods
}

然后,只要User实现所有这些方法,你就可以拥有

c.APIController.Model = new(Models.User) // Now works!

一种常见的方法可能是Save. 否则做Save一个非方法:

func Save(m Model) error {
    ...
}
于 2017-12-27T10:09:21.867 回答