В своих проектах я сделать что-то вроде этого:
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
и возвращает ошибку. До сих пор это уменьшило множество головных болей и привело к более гибкому дизайну.
Я не уверен, что это «путь», но он избегает идеи наследования и решает проблему. В логике базы данных я использую тонны отражения для захвата данных из базы данных и заполнения им объекта. Это приводит к некоторым неудачным утверждениям типа, но я думаю, что это не может помочь, когда мы пытаемся сохранить абстрактные вещи.
Посмотрите на https://github.com/jmoiron/monet/blob/master/app/models.go для хорошего примера, как это сделать. – elithrar
Другой возможностью является Gorp https://github.com/coopernurse/gorp, который хорошо работает для меня. –