Comments 12
Я немного не понял, почему без структуры "Wife" данный шаблон не нужно было бы использовать тут? Можете объяснить подробнее? Ведь если структуры "Wife" не было бы, тогда все равно было бы удобно использовать AnimalAdapter для кошек и собак.
Честно говоря до сих пор не понимаю зачем делать столь абстрактные примеры, что их зачастую поймут только люди, которые эти паттерны знают, а разработчик который хочет их понять только сильнее запутается и тем более не будет понимать где их применять.
Ну а как пример, который имеет практический смысл могу предложить любую библиотеку, которая что-то делает внутри себя и на входе просит логгер, а у вас есть логгер, который в чистом виде не подходит для этой либы.
Тут вопрос не к вашей статье в частности, а к отсутствию практических примеров в целом при разборе паттернов
Я учту пожелание. Добавлю практический пример.
Про логгер написал.
Извиняюсь, что поздно ответил, но отлично. Насколько я вижу по комментариям ниже кому-то это действительно помогло. Хотя признаюсь честно с примерами других паттернов будет сложнее. Из недавнего использовал разновидность фабрики для организации atLeastOneMessage при работе с апач кафкой. Есть желание продолжать статьи на тему паттернов? Если надо, то могу помочь в поиске практических примеров.
хорошее описание, терь лучше воспринимаю место этого паттерна
Вообще, в Go нативно реализован этот паттерн в виде интерфейсов. То есть если ты используешь хоть как-то go-интерфейсы, то ты используешь паттерн "адаптер".
Ну не совсем. Если есть какой то пакет со схожей функциональностью. Не важно какой. И его нужно прикрутить к уже работающей системе. Но сигнатуры методов разные, а значит и интерфейсы разные.
Какой бы утиной ни была типизация, вы не сможете только интерфейсами обойтись. В исходный пакет целевой библиотеки вы не залезете, она не ваша. И не добавите там вашу сигнатуру. В своем пакете вы также не прицепите нужную сигнатуру на чужой объект, вас компилятор отправит куда подальше.
Так что я бы не сказал, что интерфейсы ГО прям так сразу реализуют данный паттерн.
Без него в ГО можно обойтись запросто, когда пишешь и проектируешь с нуля. И я бы даже сказал, если у вас свежая система с адаптером на свои же библиотеки, значит что-то пошло не так :) И пора искать того, кто развел хаос в сигнатурах на уровне абстракций однотипных структур.
А вот в кейсах со старым кодом и чужими библиотеками. Иногда может потребоваться
Давайте возьмём самый простой пример использования интерфейсов. Функция принимает в качестве аргумента интерфейс. Распишем по диаграмме из вашего поста. Тогда интерфейс (как тип данных) - это адаптер, функция - клиент, реализация интерфейса - ConcreteAdapter (при этом понятно, что ConcreteAdapter чаще будет структурой с зависимостями от инфраструктуры, например БД (Adaptee)).
То есть чтобы хоть как-то воспользоваться интерфейсами в Go, вам нужно использовать паттерн Адаптер (с вариативной частью Adaptee), по-другому не получится.
Я соглашусь с вашим утверждением, если вы приведете пример расширения структуры методом вашего целевого интерфейса с условием, что структура хранится в чужом пакете, который вы не имеете технической возможности расширять.
Допустим есть структура ForeignLogger с методом LogItBro()
У вас есть в коде ваша структура MyLogger с методом LogItSister()
Вам нужно позвать метод LogItSister(), который реализует функциональность LogItBro() без расширения структуры ForeignLogger.
Т.е конструкция func (f *ForeignLogger) LogItSister() запрещена правилами Go. Компилятор выдаст ошибку на такой код.
Именно в этом суть адаптера. А не в абстракции структур, который вам принадлежат и вы их разрабатываете.
Можно псевдокодом
Буду сам пользоваться этим наглядным примером и всем советовать. Жирный плюс в карму!
Golang. Паттерн Adapter