tumbler
@tumbler
бекенд-разработчик на python

Как сделать интерфейс для иерархии типов?

В проекте есть два типа - "группа" и "элемент". У группы есть метод "получить определенные элементы". Получаем что-то такое:
type element struct {}

func (el *element) doA() int {...}
func (el *element) doB() int {...}

type group struct {
    elements []*element
}

func (g *group) getElements() []*element {...}


И есть два сервиса, каждый из которых по-своему использует элементы групп. Первому от элементов нужен только метод doA, второму - doB. Идея, которая никак не выходит из головы, звучит так: "зачем передавать сервисам полную реализацию, если можно ограничиться интерфейсами, необходимыми самим сервисам?". Например, чтобы нельзя было просто так взять и вызвать из сервиса B метод doA.

Возникают интерфейсы:

type AElement interface {doA() int}
type BElement interface {doB() int}

type AGroup interface {
    getElements() []AElement
}
type BGroup interface {
    getElements() []BElement
}


Так вот, "*group" не удовлетворяет ни AGroup, ни BGroup, потому что у getElements различаются типы возвращаемого значения. Вопрос к знатокам паттернов и го: это совсем долбанутая идея, или всё-таки есть техническая возможность ограничить сервису доступ к функционалу элемента интерфейсом?
  • Вопрос задан
  • 328 просмотров
Пригласить эксперта
Ответы на вопрос 1
@nrgian
Проверять, какой интерфейс доступен, приводить к нему:

readyForUse, ok:= element.(AElement)
if ok {
     readyForUse.doA()
}


Сергей Тихонов Сергей Тихонов
type assertions не устраивает, потому что в каждом месте, где предполагается использовать AElement или BElement, придется получать []interface{} и кастить его. Во-первых куча повторений возникает, во-вторых исходная идея про ограничение доступа интерфейсом реализовывается не в виде "есть только doA", а в виде "хочешь doA, хочешь doB - но не оба сразу".


Не типы кастить, а именно что интерфейсы.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы