Pull to refresh

Comments 63

Go совершенно не содержит классов, вместо них мы имеем гораздо более мощную концепцию композиции

Религиозный бред с первого же принципа. Что значит «более мощная, чем классы концепция композиции»? Это ведь что-то абсурдное вроде «кирпич более мощная концепция, чем трехэтажка». Почему так сказано, словно концепция концепция композиции не реализуется на классах? И чем она более мощная в Гоу, чем, скажем, в СиШарп? Ведь в Шарпах можно сделать все то же, что и в Го и даже больше. Я бы еще понял, если бы вы сказали, что в Гоу она более поддерживаемая (хотя это тоже крайне спорно), но уж более мощная — точно нет.

А знаете, почему автор так сказал? Потому что он — обычный слепой евангелист со стокгольмским синдромом. Берете недостатки и без всяких аргументов выдаете за достоинства, потому что хотите видеть именно так.

Вот такие комментарии пишут те, кто не знают Го. Сначала попробовали бы разобраться.
"Всегда предпочитайте композицию наследованию" — об этом говорит автор. В Го у вас просто нет такого выбора, в смысле нет наследования, и это хорошо.
На счёт того, что шарп может все, что и Го. Напомните, с какой версии C# поддерживает утиную типизацию интерфейсов?

Почему вы утиную типизацию интерфейсов записали в плюсы? Спорный ведь вопрос.


В Го у вас просто нет такого выбора, в смысле нет наследования, и это хорошо.

Почему отсутствие выбора это хорошо? На C# можно и наследование и композицию.

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

Вот по-этому я и сказал: «Я бы еще понял, если бы вы сказали, что в Гоу она более поддерживаемая (хотя это тоже крайне спорно), но уж более мощная — точно нет».

В целом, это положительно сказывается на проектах и их масштабировании.

Только во влажных снах. На практике — превращает код больших проектов в ужасную лапшу, в которой черт ногу сломит. Ну то есть маленькие проекты — неплохо, можно получить выиграш, но большие — опс, лучше бы мы писали на ДжавоШарпах
Можете примеры таких больших проектов привести?
Я работаю в основном в больших проектах и пока описанного вами явления не увидел.
Могу задать аналогичный вопрос. Вы сказали: «это положительно сказывается на проектах и их масштабировании». Положительно в сравнении с какими проектами на C#? Покажите мне код таких проектов, потому что я знаю огромные и разнообразные проекты на C#. Это вам и сервера, и игры, и сервисы, и библиотеки. Все, что я знаю на Гоу — значительно меньше и слабее и мой опыт работы на Гоу подтверждает, что причина этому — неподходящий дизайн языка.
Давайте по порядку:
1. я сказал «это положительно сказывается на проектах и их масштабировании». почему вопрос перевелся в контекст C#? Я могу ответить про то, что знаю я, а это PHP, python, C# в старые времена (по 1.5). Вероятно, это странно требовать от незнакомого человека, чтобы он вас уважил, а не просто поделился опытом? Давайте переведем разговор в несколько более дружелюбное русло общения двух инженеров, делящихся опытом?
2. Вы изучали вопрос о том, какие проекты на go есть?
3. С чем я сталкивался: Lazada — очень много гошного кода (мир праху его), «микросервисы» по сотне тысяч строк; проекты coreOs, всеми любимые docker, kubernates, prometheus; сейчас работаю в/с Ethereum (сейчас посмотрел 139488 строк гошного кода).
я сказал «это положительно сказывается на проектах и их масштабировании». почему вопрос перевелся в контекст C#

Если вы говорите, что что-то сказывается положительно, то будьте любезны — скажите в сравнении с чем. По контексту я понял, что в сравнении с классическим подходом к ООП, например C#. Может, вы имели ввиду в сравнении с ассемблером? Тогда я соглашусь, пожалуй большой проект на Гоу будет поддержить полегче, чем проект на Ассемблере (во всяком случае мне). Тут дизайн языка Гоу сказывается положительно.

Иначе ваше «положительно» получается, что дизайн Гоу положительно сказывается на стирке в сравнении с обычным порошком.

Lazada — очень много гошного кода

Это оно? Как-то не очень впечатляет

«микросервисы» по сотне тысяч строк

Ну с копипаст-стайлом Гоу и отсутствием Дженериком оно и не удивительно. Разве в адекватных языках придется писать такой код для каждого вида массива?
func find(slice []*TypeMuxSubscription, item *TypeMuxSubscription) int {
	for i, v := range slice {
		if v == item {
			return i
		}
	}
	return -1
}


Все, что вы сказали — это обычные проекты, которых написано пруд-пруди на других языках. Но я понимаю, что написать такое на Гоу — это подвиг)

Видите в чем проблема? Для того, чтобы показать преимущество Гоу перед другими языками вы показываете лучшие проекты на Гоу, которые обычные для других языков. Так в чем положительное влияние, если такие же проекты пишутся и прекрасно поддерживаются и на других языках?

С другой стороны я смутно представляю, как можно написать и поддерживать на Гоу, скажем такую игру как Cities: Skylines. Особо учитывая, что моддеры могут поменять любой ее кусок. Или такое ПО как Blender.
Я не сказал, что написать такое — это подвиг.
Я сказал, то в го есть такие же большие проекты, как и в других языках, но вход в них, как и масштабирование, легче. Что собственно вы и подтвердили только что.
Я не называл лучшие примеры — я где-то говорил про лучшие? Я назвал те, в которых непосредственно работал.
А Lazada — вот тут, самый большой e-commerce в SEA.

Написать можно что угодно на чем угодно Тьюринг полном. Вопрос в скорости входа, поддержки и соответствия инструмента.
Так я никогда не возьму Go, если надо считать цифры. Статистика, ML, DL, моделирование — боже упаси брать go.

Я ответил на ваши вопросы. Ваша очередь.
Я сказал, то в го есть такие же большие проекты, как и в других языках, но вход в них, как и масштабирование, легче. Что собственно вы и подтвердили только что.

Простите, что в Гоу есть несколько больших проектов — я знаю. Но вы сказали:

В целом, это положительно сказывается на проектах и их масштабировании.

Я не вижу положительной корреляции на примере этих проектов. Вы заявили о положительной корреляции — я попросил пример положительной корреляции.

Есть более сложные проекты на других языках, уровень которых на Гоу не писался и это пример отрицательной корреляции.

Я вам не привел в пример цифры. Я вам привел в пример ГУИ+3д-софт и игрушку.
Как из
Есть более сложные проекты на других языках
может следовать
уровень которых на Гоу не писался и это пример отрицательной корреляции.
?
Давайте уже перейдем на серьезный разговор? Начиная с утверждения статистики о
correlation does not imply causation
.
Я привел несколько больших проектов. Вы согласны, что они большие? Если нет, то собственно вот и поговорили.
correlation does not imply causation

С этим я согласен. Моя «отрицательная корреляция» — не больше, чем предположение о существовании отрицательной корреляции.

Вы согласны, что они большие?

Я не буду поддаваться на ваши манипуляции) Это не важно, т.к. см. ниже

Самое важное вы почему-то упорно игнорируете, видимо потому что не хотите признавать свою неправоту. Вы утверждали о том, что дизайн Гоу положительно сказывается на поддерживаемости (не «тоже можно поддерживать», а именно «положительно»), но никаких доказательств этому не привели и съехали в итоге «ну ведь на гоу тоже есть довольно большие проекты».

Если бы вы с самого начала вместо

В целом, это положительно сказывается на проектах и их масштабировании.

написали то, что стараетесь утверждать теперь:

В целом, на Гоу тоже пишут и поддерживают большие проекты.

То всей этой ветки не было бы. Проблема в том, что одним недоказаным утверждением вы попытались доказать другое. А теперь пытаетесь из меня вытянуть согласие, что Докер — большой проект. Вот только вы просто этим уходите от темы, что никаких доказательств того, что Гоу имеет преимущества в поддержке коде — нету.
А можно критерии больших проектов?
Число людей в команде, нагрузка, whatever? А то мне кажется вы не сходитесь в оценке больших проектов.
Чуть подробней о критериях, пожалуйста: сколько LoC и сколько людей?
30 человек на проекте — это большой проект? А 10? А 100?
Миллион строчек кода? 10 миллионов? 5 тысяч?
Большой проект — это более сотни разработчиков, лучше сотни.
Число строк кода — десятки тысяч на отдельный репозиторий. Или в сумме речь идет о более чем миллионе.
Ок, спасибо.
Значит я всегда работал над маленькими проектами, если судить по числу разработчиков.
Потому что этот подход удобнее.
Представьте, что класс какой-то внешней библиотеки подходит по методам, но однако не поддерживает нужный вам интерфейс. И вот вы идете и пишете обертку над этим классом, хорошо, если он не sealed. В Go вы просто его используете, потому что он уже подходит, зачем предпринимать лишние шаги? Здорово же, никакой спорности тут нет.

Отсутствие выбора хорошо по той причине, что мы не живем в мире розовых пони и единорогов — большинство разработчиков мыслят только в парадигме наследования. Это порождает монстров. Разработчики Go пошли на серьезный шаг — построили язык, который доказывает, что концепция наследования оказалась ошибочной и без нее можно обойтись (кол-во успешных проектов на Go подтверждают это).
Можно не значит, что нужно.
Здорово же, никакой спорности тут нет.
Зато как иногда бывает прятно разбираться в чужом коде, в попытках понять «а кто же этот интерфейс реализует» или «хм, это имя тут просто так, или это мы реализуем некий интерфейс». Особенно если код идеоматичный, и методы называются Get(), New() и т.п.

большинство разработчиков мыслят только в парадигме наследования
У вас есть исследования или статистика на этот счет?

что концепция наследования оказалась ошибочной и без нее можно обойтись
Я наверное не буду оригинальным… Но посчитайте количество успешных проектов на C. А потом найдите там наследование. А еще найдите там сборку мусора. И рефлексию. И зеленые потоки… Ох, какие же это все ошибочные концепции, язык C доказывает это!
Исследований нет, но то, что в коде часто встречаются наследованные монстры — наводит на эту мысль. Возможно мне не везло просто, вы правы.

Язык СИ появился куда раньше, приводить его в пример — это передергивание. Ну и у него есть своя ниша высокопроизводительных приложений.
Представьте, что класс какой-то внешней библиотеки подходит по методам, но однако не поддерживает нужный вам интерфейс
А что делать если подходит по методам, но не подходит по смыслу, не делает того чего нужно?
Вы не поверите — не используйте его, вас же никто не заставляет, правда?
И чего? Возможность привести объект к интерфейсу никого не убивала.
построили язык, который доказывает, что концепция наследования оказалась ошибочной и без нее можно обойтись (кол-во успешных проектов на Go подтверждают это).

Не подтверждает. Успех говорит, что количество достоинств опережает количество недостатков. А вот что считать достоинством, а что недостатком — вопрос статистики.


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

Разработчики Go пошли на серьезный шаг — построили язык, который доказывает, что концепция наследования оказалась ошибочной и без нее можно обойтись (кол-во успешных проектов на Go подтверждают это).

То, что без чего-то можно обойтись не означает, что что-то ошибочное. По вашей логике количество проектов на Джава показывает, что концепция создания языка Гоу как такового — ошибочна.
Не показывает. Джава гораздо раньше появилась и имела свои преимущества перед другими языками/платформами на ТОТ момент, что и вызвало взрывной рост числа приложений на этом языке.
Ну ок, по вашей логике, популярность PHP, который вышел в 1995 и имел взрывной рост числа приложений показывает ошибочность подходов Haskell (1990), Lisp (1958), Erlang (1987)?
Почему отсутствие выбора это хорошо? На C# можно и наследование и композицию.


Наличие многих фич, альтернативных путей решения, в языке программирования вовсе не плюс, а чаще минус.

Был такой язык программирования PL/2.
Чего только не было в описании синтаксиса. Умер от собственной сложности. Никто не знал и 30% возможностей языка, кроме десятка человек во всем мире (включая авторов).

Программисту не нужно забивать себе голову синтаксическими возможностями.

1. Голова у программиста и так забита. Пусть лучше она будет сосредоточена на предметной области, чем на сложности используемого инструмента.

2. Подавляющее большинство середнячки. Не нужно обижаться, так всегда было есть и будет во всех профессиях. Не нужно позволять программистам «флудить» в коде. Да и высококвалифицированные программисты зачастую увлекаются. Сложность ради сложности, фичи ради фич, я и так могу и эдак, давай-ка попробую и это и то. Эдакое профессиональное самолюбование, а не решение конечной прикладной задачи.

3. Код программисты пишут, чтобы его читать. Нет, не компилятором. А глазами другого программиста, его коллеги. Или своими глазами через полгода. Код должен быть не переусложнен синтаксически.

Код должен быть стандартен и прост, как не скучно это звучит. В этом контексте стандартное форматирование Go еще один плюс. Собственно, даже автор утилиты для форматирования «go fmt» не был в восторге от того, по каким правилам форматируется код в Go. Но при этом он прекрасно понимал силу легкости понимания вашей программы коллегами.

Все это не имеет значения пока вы работаете один.
Но в команде — некоторые вещи оказываются очень важны.
Вот такие комментарии пишут те, кто не знают Го. Сначала попробовали бы разобраться.

И пробовал, и разобрался.

«Всегда предпочитайте композицию наследованию» — об этом говорит автор. В Го у вас просто нет такого выбора, в смысле нет наследования, и это хорошо.

Так более мощная или нет выбора? И почему противоставляется, если композиция реализуется и на классах. Так и пишите: «на Гоу нету выбора, потому он лучше».

А то пишут: «вот в классах наследование, а не композиция, как в Гоу — потому они хуже». Ну ложь ведь.

поддерживает утиную типизацию интерфейсов?

Про утиную типизацию согласен, ошибочка тут моя вышла. Ну так пусть будет написано в статье:

Go совершенно не содержит классов, вместо них мы имеем гораздо более мощную концепцию утиной типизации


Тогда начнем спор по существу недостатков утиной типизации, к которому пришли только на третьем уровне вложености, а не по поводу лжи в статье. Но ведь утиная типизация — это не так пафосно, как «Го лучше классов, потому что в нем композиция»
Более мощная и нет выбора. Да
кирпич более мощная концепция, чем трехэтажка

В ваших словах есть доля правды, но это зависит от точки зрения, а по поводу цитаты- я бы сказал иначе. «Здание более мощная концепция, чем трехэтажка.» Да и нет тут ничего нового, это не автор поста придумал en.wikipedia.org/wiki/Composition_over_inheritance
я бы сказал иначе. «Здание более мощная концепция, чем трехэтажка.»

Тогда уж наоборот: «Трехэтажка более мощная концепция, чем здание». Потому что композиция — только один из методов ООП, как трехэтажка — только один из видов зданий.

Да и нет тут ничего нового, это не автор поста придумал

И только автор поста додумался противоставить композицию и ООП вцелом, что не имеет никакого смысла.
И только автор поста додумался противоставить композицию и ООП вцелом, что не имеет никакого смысла.

Откуда такие выводы? Автор говорил не о ООП, а о наследовании. Да в том же C# композиция реализуется ничем не хуже, но тут уже работает филисофия Go -минимализм, авторы тщательно избегают обростания языка возможностями, без которых можно обойтись. В данном случае думаю подразумевалось то, что при выборе между композицией и наследованием -первая концепция показалась авторам языка и автору поста более «мощной» (мне не нравится это слово, но я максимально пытался сохранить стиль изложения автора).

Думаю вам стоит относится к миру менее агрессивно и для начала попытаться понять о чем идет речь. Никто не говорил, что наследование или ООП в целом несет в мир что -то плохое, речь о том (и опять таки в статье это проговаривается), что минимализм -это меньше ошибок и более явная реализация принципов SOLID и о том, что в контексте других ЯП очень часто говорят вспоминая о том, что они «раздуты, многословны и перегруженны» и в Go пытаются этого избежать. Очень много чего в языке не появляется именно с целью сохранения концепции минимализма.
В данном случае думаю подразумевалось то, что при выборе между композицией и наследованием -первая концепция показалась авторам языка и автору поста более «мощной»

Но ведь в статье написано совершенно иначе. Вы толкуете статью, как какой-то религиозный талмуд, который можно толковать как то выгоднее фанатикам. Я вам второй раз процитирую:

Go совершенно не содержит классов, вместо них мы имеем гораздо более мощную концепцию композиции


Я вам еще раз повторюсь:
1. Вместо классов
2. Более мощная
3. Концепция композиции

Именно такой бред написан в статье. Не все ваши толкования, а именно это. Не про минимализм. Не про утиную типизации. Не про недостатки наследования.

И вообще, наследование — это не плохо. Его просто применяют часто тогда, когда не нужно и больше подходит композиция.
Вы занимаетесь словоблудием и придираетесь к фразе вырванной из контекста, какое отношение ваш последний комментарий имеет к «противопоставлению композиции и ООП», о котром вы говорите? В каком месте было сказанно, что композиция не может быть реализованна с помощью классов? Можно переформулировать иначе:
Вместо классов, которые существуют в ЯП исключительно для обеспечения реализации механизма наследования у нас есть гораздо более мощный инструмент — композиция.


Вы толкуете статью, как какой-то религиозный талмуд, который можно толковать как то выгоднее фанатикам

Эта статья является расшифровкой выступления и ее толкование -это пояснение того самого контекста.
В каком месте было сказанно, что композиция не может быть реализованна с помощью классов?
Ну если композиция может быть реализована с классами, то почему Go мощнее?
почему Go мощнее?

Вы как и предыдущий автор придираетесь к словам кейнота конференции, которые теряют смысл вне контекста но еще и говорите о том, чего нет.

Никто такого не говорил, мощнее не Go, в данном случае (на сколько я могу понять) речь шла именно о наследовании, говорилось о классах, по скольку обеспечение реализации механизма наследования их изначальная задача. И никто не говорил, что Go мощнее, говорили о том, что композиция более мощный инструмент, чем наследование. Более того, мощный -не означает, что он «лучше», просто возможности предоставляемые им шире.

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

да ладно
что композиция более мощный инструмент, чем наследование.

композиция это серебрянная пуля?
нет просто ее мощь в сравнении с наследованием проявляется в большей гибкости. Это не взаимоисключающие понятия.
Авторы Go видимо думают иначе
В каком месте было сказанно, что композиция не может быть реализованна с помощью классов?

Черт! Я ведь вам уже трижды процитировал!

Go совершенно не содержит классов, вместо них мы имеем гораздо более мощную концепцию композиции

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

У нас на конференции совершенно не было фруктов, вместо них мы положили в тарелки значительно более вкусные яблоки

Я понимаю, что когда что-то связано с Гоу, то фанатам все выглядит корректно, но теперь, когда я перевел на пример с фруктами — вы понимаете абсурдность фразы?
— Как яблоки могут быть вкуснее фруктов, если яблоки — тоже фрукты?
— Как композиция может быть мощнее классов, если через классы реализуется и композиция?

к фразе вырванной из контекста

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

Как у вас написано:
Класс должен иметь одну и только одну причину для изменений.
-Роберт С. Мартин

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


Как необходимо было сказать на конференции, убрав при этом манипуляции, но получив при этом меньше лайков от хипстеров:

Класс должен иметь одну и только одну причину для изменений.
-Роберт С. Мартин

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

Видите? Никакого «более мощная, чем классы». И «менее мощная, чем классы». Просто другая. И никакого бреда из разряда «яблоки вместо фруктов».
Ок, я понял что вам не нравится. Хоть мне и кажется, что автор просто плохо подобрал слова, а говорите вы об одном и том же, пусть будет так.

По сути вы правы.

Я не заинтересован в том, чтобы быть чьим -то адвокатом и не смотря на то, что мне нравится Go, я просто понимаю свои задачи и не собираюсь писать на нем интернет магазины избегая наследования.

А вы пробовали композицию реализовать на классах? Пусть даже с использованием наследования макросов и темплейтов

А в чем проблема реализовать композицию на классах?
Из практических будет diamond problem, отсутсвие method promotion, сложности с последующим кастованием. Они конечно решаемы, но это будут костыли похлеще копи-пасты изза отсутсвия генериков у го.

Если интерестно — можно тутже в треде попробовать. Если я ошибаюсь, буду реально рад
class Fruit {
    //...
}
class Apple {
    private Fruit fruit = new Fruit();
    //...
}
class Fruit {
    //...
    public void Name() {
        System.out.println("Fruit::Name");
    }
}
class Apple {
    private Fruit fruit = new Fruit();
    //...
    /* // Method promotion vvvvvvv
    public void Name() {
        fruit.Name();
    }
    */
}
public class MyClass {
    public static void main(String args[]) {
        Apple apple = new Apple();
        apple.Name(); // <---!!!!!!!!!!!
    }
}


Method promotion ручками копипастить? Тоесть буквально на каждую композицию каждый метод?
UFO just landed and posted this here
отсутсвие method promotion
Так он далеко не всегда нужен. Чаще даже вреден, ибо позволяет «утекать» деталям реализации, помогает нарушать инвариант и раздувает интерфейс (тут вроде как говоирли про принцип разделения интерфейсов).

Если же он реально нужен, то, как вы и указали, есть куча решений.
Я не говорю про банальную кодогенерации в IDE. Можно делать кодогенерацию данамически. Или воспользоваться языком-транслятором, вроде Xtend.
Можно придумать и более извращеные варианты. Но все равно лучше отказаться от method-promotion в сторону явного разделения интерфейсов.

diamond problem
Ну так ведь подобная проблема никуда не девается и в Go.
Если, скажем, B и С композирют A, а потом X включает B и C одновременно, то мы получаем 2 честных копии A. И компилятор далеко не всегда укажет на подобные ошибки. Например вот.

cложности с последующим кастованием
Ну это вообще Go-специфичные проблемы, связанные с дубовостью его системы типов.
method promotion — lombok, кодогенерация, макросы редакторов и пр — это не pure language — оно конечно же «считается» но костыль. с подобными костылями можно даже на ассемблере писать :E
можно через наследование — но тогда будет diamond problem.

cложности с последующим кастованием — если реализовывать через свойства, то апкастить с костылями же приделся.

diamond problem — там по коду бага не существенная, но и с правильным конструктором для Х она не даст работать. по полям есть вот такой дело (хотя в данном случае это какбэ не поная реализация Б и Ц — методы для записи\чтения есть — но нет для чтения\записи).
по методам надо явно указывать от какого предка вызываешь.
method promotion — lombok, кодогенерация, макросы редакторов и пр — это не pure language — оно конечно же «считается» но костыль. с подобными костылями можно даже на ассемблере писать :E
можно через наследование — но тогда будет diamond problem.
Ну это касательно Java, этот язык весьма многословен. Если расматривать, скажем, Xtend как самостоятельный язык — это уже pure language. Т.е. это конкретная фича конкретного языка, не связанная с «классы» или «не классы».

cложности с последующим кастованием — если реализовывать через свойства, то апкастить с костылями же приделся.
Я не совсем понимаю, про какое кастование идет речь. Можете привести конкретный пример?

diamond problem — там по коду бага не существенная, но и с правильным конструктором для Х она не даст работать. по полям есть вот такой дело (хотя в данном случае это какбэ не поная реализация Б и Ц — методы для записи\чтения есть — но нет для чтения\записи).
по методам надо явно указывать от какого предка вызываешь.
Этот пример и не должен работать :)
Но я опять запутался, если уж вызывать методы по полному имени, то как же method promotion?..

В любому случае и в Го, и в Java (с любом методом из указанных мной) мы получаем две копии агрегированного объекта, и ошибки компиляции/выполнения об «неодназначности». В Go ошибки может не быть, если мы явно не вызываем конфликтный метод, поэтому можно «не заметить» дублирования. В Java получаем ошибку компиляции всегда (попытка добавить в класс 2 метода-загшулки с одинаковой сигнатурой). В чем преимущества «безкласcового» подхода Go?
и в джаве вроде надо заранее указывать какие интерфейсы класс реализует. в крестах задних наверное через концепты можно както извернуться.
сложности с последующим кастованием
А как это решается в Go?
про последующее кастование выше указал что я имел ввиду. но type assertion работает как dynamic cast если через инетерфейсы работать.

А если отбросить евангелистическую подачу материала, то о solid можно и не говорить вовсе. Лучше бы на примере показали как этому следовать в go. Я вот форк https://github.com/r3code/clean-go сделал от clean-go чтобы посмотреть инверсию зависимости, тут как раз есть части solid.

Почитал. Имеет место быть пытытка привязать принципы для построения ООП программ к не-ООП языку. Ведь по сути эти принципы это что? Это свод высокоуровневых рекомендаций и практик того, как следует писать ООП-программы, чтобы они были кошерными…

При попытке все это натянуть на Go получается как-то не очень, если честно: или принципы искажаются до неузнаваемости, теряя свой начальный смысл, или сводятся к тривиальным и довольно очевидным вещам.

По пунктам

Принцип единственной ответственности
Универсальный принцип, применимый не только к ООП — каждый объект/функция/процедура/модуль/класс/актор/сервис/компонент/пакет/допишитесамичтохотитетут должен выполнять/нести отвественность за одну функциональность. Ну собственно да, тут сложно поспорить.
Но блин, это ведь НЕ сводится к «давайте своим пакетам хорошие имена».

Даже пример приводится кривой — 'net/http', который выполняет роль и криента, и сервера, нарушая наш принцип. Работу с http-прокси тоже туда? А куда spdy или HTTP2? Потом добавим работу с REST, санитайзеры http… Незачет.

Принцип открытости/закрытости
Встраивание действительно делает «дописывание» кода проще и легче.
Но давайте глянем, скажем, сюда Robert C. Martin «The Open-Closed Principle», C++ Report, January 1996
выдержка
Modules that conform to the open-closed principle have two primary attributes.
1. They are “Open For Extension”. This means that the behavior of the module can be extended. That we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applicationАгаs.
2. They are “Closed for Modification”. The source code of such a module is inviolate. No one is allowed to make source code changes to it.
It would seem that these two attributes are at odds with each other. The normal way to extend the behavior of a module is to make changes to that module. A module that cannot be changed is normally thought to have a fixed behavior. How can these two opposing attributes be resolved?
Хм, уже немного другой смысл, правда? Открытые — значит мы можем не просто дописать сбоку код, который будет базироваться на существующем, но еще и поменять его поведение.
Закрытие — это не значит что мы не можем переопределить некую функцию и у нас нет виртуальных методов… Нет, это значит что нам не должно быть необходимым менять исходне коды объекта, чтобы менять его поведение.

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

Принцип подстановки Барбары Лисков
Ох… Тут все совсем мрачно. Принцип ведь про ковариантность/контрвариантость. Этого в Go принципиально нет. Про то, что делать объекты нужно так, дабы вместо типа всегда можно подставить его подтип, но не наоборот.

В итоге идею извращают до «используте интерфейсы; если уже их имплементируете, то делаете это корректно». Ну класс, глубоко то как :(

— Принцип разделения интерфейса
Вот тут… ок. Делаем интерфейсы поменьше и поконкретнее.

Принцип инверсии зависимостей
И снова «ох».
Итак, как я представляю себе то, о чем Мартин тут говорит, в основном в контексте Go-это структура вашего графа импортов.
Вообще то в Go зависимость «интерфейс-реализация» НЕ предполгаете иморт (спасибо уткам за это). Так что стурктура графа импортов тут поскольку-постольку.
Если мы определяем локальный интерфейс для работы с внешним модулем, то мы добавляем неявную зависимость от этого интерфейса. А потом идут какие-то мутноватые рекомендации насчет графа импортов.

В итоге хочется подвести итог.
Не надо пытаться натянуть принципы/бест-практики из ООП языков (с классами, наследованием и блекджеком) в языки без оных.
Мне не понятно, зачем описывать SOLID в Gо, «приклеивать» ООП и всякое то, что от чего разработчики Go, по большому счету, отказались…

какая-то речь про классы и преимущества мифической композиции перед ними.

можно, простите, на Pascal налепить подобие ООП, как-то придерживаться SOLID и т.п…

смешивание все во едино — добром не кончится…

хоть бы задачи какие приводили…

мое понимание:
— где удобно классами и структурами — берите язык который поддерживает ООП, нормальные наследования, инкапсуляции и т.п.
— можно обойтись без классов — берите любой удобный процедурный язык с которым дружите.

Простите, идиотизм какой-то…

так и бывает… смотришь решение бизнес-задачи в виде одной программки, логики чуть-чуть, но б*ять применяемые паттерны, абстракции и куча всего, что показывает крутость программиста, а не логику работы программы… мозг можно сломать…

люди иногда извращаются над кодом, предполагая, если логику менять потребуется — то это будет кто-то другой… а вот шишь )

простите за простыню…
Sign up to leave a comment.

Articles