Pull to refresh
66
0
Andrei Zhlobich @anjensan

Human

Send message
Да нормально всё там.

Ну коли так, то бесцельно спорить с вами я вижу смысла ровно ноль :)


Решите, пожалуйста, упражнение без применения наследования, не важно на каком языке, покажите класс!

Суть таких задач ведь не написать идеальное решение (пример все равно стерильно искусственный). Суть — на своем личном опыте понять те или иные концепции, в данном случае самому придти к пониманию, что либо мы используем наследование, либо отходим от ООП. Вы выбрали вариант два, перейдя к процедурному стилю (вынесли общий код во внешнюю процедуру, забив на инкапсуляцию кстати).


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

Потом я спросил, будет ли объектно ориентированным код, написанный на Go, если там наследование будет не нужно.

Окей. Отвечу. От может быть как объктно-ориентированным, так и нет. Как, например, может быть объектно-ориентирпованным код на С. Целые объектные фрейморки на С есть. Что, однако, не делает этот язык ООП.


По поводу вашего упражнения — плохо. Вы пишете про "код, который рассчитан на наличие методов у самих сущностей", но ваши сущности эти методы не имеют.
Вызов RectShape(1).areaSqrt() вернет что? Бросит ошибку.


Ну а ваше решение упражнения со звездочкой — типичное гоферовское (это не комлимент). Дабы оптимизировать один метод (areaSqrt) что сделали? Правильно, скопипастили все методы из другой сущности и переписали один из них, так что у нас есть сейчас две реализации 'halvedArea'. Короче опять незачет.

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

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


В целом да (хотя пример очевидно совсем уж искуственный, и наследования в конкретно этом куске нету, ибо оно тут не нужно).

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


Я не понял в чём сложность вернуть корень из площади, а код вот, пожалуйста )).

Хорошо, а теперь для тренировки основ:


  • сделайте так, чтобы у самих сущностей *Shape были методы halvedArea и т.п. Ибо сейчас ваш код по сути эквивалентен такому;
  • (задание со *) сделайте так, чтобы для SquareShape не происходило бесполезного возведения в квадрат а затем извлечения корня. Ибо это а) медленно, б) теряется точность.
И так как от того, чтобы быть ООП языком Go отделяет возможность переопределить метод, получается, что именно эта возможность ухудшила бы язык. Ну, то есть Template Method это выходит антипаттерн, а не паттерн вовсе.

Вы неверно истолковали мою мысль. Решение многих задач через наследование может быть проще (быстрее и легче запилить), но дороже в плане поддержки в долговременной перспективе. Особенно если у вас большой проект, и много "вчерашних студентов" и просто не очень сильных программистов. Читайте "проще натворить фигни".


Ну вот этот код он объектно ориентированный?

В целом да (хотя пример очевидно совсем уж искуственный, и наследования в конкретно этом куске нету, ибо оно тут не нужно). Попробуйте теперь в качестве упражнения добавить сюда метод "вернуть удвоенную площадь". А потом, в качестве усложненного упражнения, добавить метод "вернуть корень из площади" и подумать, как все это можно оптимизировать/улучшить.

И в Go наследования нет вообще и никак нельзя сделать так, чтобы в одном классе можно было воспользоваться методами, которые объявлены для другого?

Воспользоваться можно, переопределить нельзя.


если бы в Go было бы какое-то наследование, то Go был бы объектно-ориентированным даже по вашему "старому" определению?

Ну да. И стал бы при этом хуже, нежели сейчас.


А вообще ООП сейчас проникло повсюду, очень удобный концепт получился.

Ага, настолько удобный, что дизайнеры языков от него совершенно сознательно отказываются (дада, я про Go или, скажем, Rust). Но дабы не потерять популярность "у народа" вынуждены писать, "ой… ну да и нет...". А то иначе плебс не примет.


И код, в котором не использовалось наследование не был объектно ориентированным кодом?

Может быть. На JS вполне можно писать в процедурном стиле.

Итого, инкапсуляция есть, полиморфизм есть, почему тогда Go это не объектно ориентированный язык?

Наследование забыли =)


На самом деле полиморфизм есть во всех более-менее высокоуровневых языках. Аналогично с инкапсуляцией. Я уже приводил ссылку на статью на вики — есть пример инкапсуляции на C.


Так что если следовать вот такому "новому" определению ООП (где вместо 3 принципов оставили только 2), то Go выходит объектным. Но тогда получится, например, что и Haskell тоже ООП-язык… Да блин, тогда не-ООП языки вообще останутся? :))


А вот extends появилось сравнительно недавно, но ООП в джаваскрипте было и до этого.

Ну так и наследование ведь было, называлось prototypal inheritance.

Был бы не ООП, так бы и написали, что не ООП

Я поправил, бгагодарностей не надо.


И в Go этого нет?

Я этого не утверждал. С моей точки зрения, это как раз тут имеется.


И, главное, когда говорят про ООП под инкапсуляцией имеют в виду именно это?

Да. Именно это и имеют в виду — объединение кода и данных. Иные трактовки идут от безграмотности.


Вон в джаваскрипте инкапсуляции нет, наследования нет а ООП есть. Это потому что там таки есть полиморфизм.

Ну разумеется инкапсуляция в джаваскрипте есть.
Наследование там тоже есть, даже ключевое слово extends завезли :D

"И да и нет" != "написано, что Go — ООП язык". Это скорее "а фиг его знает", или даже "ой… ну если придумать свое определение ООП..." :)


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

Неа, это упаковка данных и кода в одной сущности.


Полиморфизм обязательно.

А почему, вы пользуетесь каким-то конкретным определением ООП?

Но сослались на текст, в котором написано, что Go — ООП язык ))

Там это НЕ написано.


получить доступ к полям реализации, которых в интерфейсе нет? Прямо как в питоне?

Это не связяно с инкапусляцией.


Которое в ООП не обязательно

А что обязательно?

Простите, конечно, но вы сравниваете несравнимые вещи: Jmeter не на Go, и там нету Yaml!

Ага-ага. А процедурное программирование — это программирование с использованием процедур. А структурное программирование — это программирование с использованием структур. А функциональное — это когда программирование с использованием функций.


Короче опять чушь несете.

Я вам не хамлю. Я констатировал факт того, что вы забыли свои же недавние фразы.


Следуя оффициальной терминологии в C# именно что generics. Причем "Generic programming" != "Generics".


Прежде чем пороть чушь, пройдите по своей ссылке, и почитайте что в C# именно что generics, и что даже code generation является одним из подходов к Generic programming. И что type erasure не является необходимым атрибутом generic'ов. И вот дабы это наглядно показать, вам привели в пример C#. На что в ответ пошла чушь навроде "В C# те же шаблоны". Глупо и некрасиво.

В C# те же шаблоны, только специализируются они в рантайме.

или


Да какая разница к чему он ближе, если по факту это шаблоны.

Проблемы с памятью?

Можно долго спорить над терминологией, но прям офф доки говорят что это дженерики. Но вы, конечно же, а как иначе, умнее этих недотеп из МС…


https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/differences-between-cpp-templates-and-csharp-generics

type erasure запили как компромисс, который позволили по минимум переделывать виртуалку, коих для джавы мнооого. А еще сделать весь старый код совместимым с новой джавой.


Наличие type erasure в обной из реализаций дженериков не означает что оно есть везде.

Ну и как, например, "по хорошему" обойтись без кастов из interface{} при использовании, скажем, модуля heap? Научите плз.

Меня больше пугает что ихего начнут использовать везде, там где надо, там где не надо или просто потому что могут, и это модно стильно молодежно.

Это вы щас историю успеха Go описали?


Не переживайте, наговнокодить можно и сейчас, было бы желание. Врядли ситация кардинально поменяется.

это никого не волнует

Это не волнует фанатиков и дураков. Так то народ постоянно стонет и ругается на обработку ошибок в Го (точнее на ее отсутствие). Блин, этож самая популярная тема похейтить сей яызк :D


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

Ну во-первых, тут три строки. Там три строки… Потихоньку набегает. А во-вторых — а зачем так привязываться к filter? Ведь можно поговорить о более удачных примерах из оригинального пропозала


Там приводят


func Keys(m map[K]V) []K
func Uniq(<-chan T) <-chan T
func Merge(chans ...<-chan T) <-chan T
func SortSlice(data []T, less func(x, y T) bool)

Неужели ни разу не понадобилась фунция Keys?


а написать пару раз фильтр на 3 строки за проект

А, понял. Проекты просто махонькие. Ну тогда норм.

Ну это если функция фильтрует слайсы, то она
"бесполезная". Ну гляньте на примеры из статьи https://blog.golang.org/pipelines, например функцию merge. Как же весло, когда нельзя такую функцию добавить в непонятный пакет, а нужно копипастить по большому проекту!


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

Ну добавите вы проверку. Сделали такую проверку в рантайме, тип не тот, паники нету… Но что дальше? Напечатать в лог "Unsupported!!" и продолжаете выполнение? Т.е. в вашем понимании это "все работает"?

1
23 ...

Information

Rating
Does not participate
Location
Warszawa, Польша
Date of birth
Registered
Activity