2013-07-21 2 views
2

Я хочу создать модели для своей структуры, написанные в go, и я не уверен, как их компоновать таким образом, чтобы использовать общие методы взаимодействия с базой данных: сохранять, обновлять, удалять.Как сделать модель в Go

Обычно я делаю это, создавая абстрактный родительский класс модели для всех конкретных моделей, но Go не имеет наследования. Вместо этого вы должны использовать вложение и компоновку, но я не вижу, как я могу вставить класс модели и сохранить данные этого класса.

Я вижу другой вариант создания класса модели, который встраивает в него конкретный тип модели, но я не вижу интерфейса, который применим ко всем моделям, если он не был пустым. Это приносит с собой неуверенность в том, что все можно считать моделью.

Что делать?

+0

Посмотрите на https://github.com/jmoiron/monet/blob/master/app/models.go для хорошего примера, как это сделать. – elithrar

+0

Другой возможностью является Gorp https://github.com/coopernurse/gorp, который хорошо работает для меня. –

ответ

4

В своих проектах я сделать что-то вроде этого:

type Storable interface { 
    // called after unmarshalling from the database 
    Init() error 
    // called when an object is being deleted 
    // this is useful if the object needs to delete other objects, 
    // change state on a remote server, etc. 
    Destroy() error 
    // called after Init, helps separate initialization from 
    // sanity checks (useful to detect errors before using a potentially 
    // invalid object) 
    Validate() error 
    // type of this object, stored in the database in `Save` and `Update` 
    // so it can be read out in `Get` 
    Type() string 
} 

Если вы работаете с базой данных SQL, вы могли бы сделать что-то вроде этого:

type Schema map[string]reflect.Type 

type SQLStorable interface { 
    Storable 
    Schema() Schema 
} 

Тогда в базе данных, я имеют такие функции, как это:

func Get(id string) (Storable, error) 
func Save(Storable) error 
func Update(id string, Storable) error 
func Delete(id string) error 
// register a type with the database (corresponds to the Type() in Storable) 
func Register(typ string, reflect.Type) 

Я держу кэш объектов в базе: map[string]Storable. Это позволяет мне реализовать логику кэширования для уменьшения времени поиска (не нужно восстанавливать объекты каждый раз, когда они считываются из базы данных).

В моем проекте у меня есть много пакетов, которым нужно поговорить с объектами из других пакетов. Поскольку управление цепями зависимостей будет кошмар, я создал систему обмена сообщениями, которая использует базу данных:

type Message map[string]interface{} 
func Send(id string, Message) 

И я добавил Receive функцию Storable, которая принимает Message и возвращает ошибку. До сих пор это уменьшило множество головных болей и привело к более гибкому дизайну.

Я не уверен, что это «путь», но он избегает идеи наследования и решает проблему. В логике базы данных я использую тонны отражения для захвата данных из базы данных и заполнения им объекта. Это приводит к некоторым неудачным утверждениям типа, но я думаю, что это не может помочь, когда мы пытаемся сохранить абстрактные вещи.

+0

Итак, чтобы сохранить модель, вам нужно сделать что-то вроде db.Save (user) ? – Charles

+0

Да, точно. Если вы не хотите определять 'Type()' в 'Storable', то передайте дополнительный параметр каждой функции DB, задающей тип. Я делаю это, но я чувствовал, что 'Type' часть интерфейса сделала это яснее в этом сообщении. – tjameson

+0

Кстати, я также снялся в твоем вопросе, потому что меня очень интересуют подходы других людей. – tjameson

Смежные вопросы