Анти-паттерны проектирования.В тред призываются программисты.Пацаны, нужна ваша помощь.Встал вопрос с одним анти-паттерном - Вызов предка (Call super).Поясните мне чем он плох? гугл нормального ответа не выдал.А если точнее, то вопрос такой.У меня есть класс, который содержит в себе строки с названием категории и типа класса, так же содержится метод, который вносит в эти строки данные. От этого класса наследуется ещё 2 других класса. Оба эти класса вызывают родительский метод инициализации строк, но не просто вызывают, а расширяют его, добавляя новый необходимый функционал в метод. Но перед тем, как этот расширенный метод начинает работать, он вызывает базовый родительский метод инициализации, чтобы сначала внести данные в строки типа и категории.Как я вычитал в гугле - тут на лицо анти-паттерн "Вызов предка", но я не понимаю как от него избавиться.У меня есть вариант везде писать инициализацию всех строк, но тут уже нарушается анти-паттерн "Копи-паст".Что делать? Бочку не предлагать.
Потому что паттерн прямо противоречит основе в твоём коде, тебе надо использовать CSS подргрузку для адекватной работы команды.
>>215126192Но если я буду каждый раз разбивать один класс на кучу других - у меня будет огромное число классов с одинаковыми данными, которые я просто скопирую.Это ведь тоже анти-паттерн "Копи-пасты".Мне проще сделать единый класс с данными, от которого будут наследоваться другие классы, у которых есть точно такие же данные.
>>215126275>нахуй ты на эти анти паттерны дрочишьПотому что учусь и мне стоит их знать, иначе вечно буду хуйню писать.
>>215126831Я, бляжд, хочу на работу в It за 20 ударов плетей в месяц пойти.Мне нужно знать как избавляться от ошибок.
>>215127070Всё просто.Есть родительский класс, у которого два свойства.string _type иstring _categoryЕсть метод initialization()Который эти строкам присваивает значение.Вот и весь класс.От него уже идут дочерние классы, которые эти строки используют при получении названия (нужно, чтобы удобнее было ориентироваться в проводнике) и для сортировки (собственно по типу и по категории).
>>215127475В конструкторе родительского класса?Получается я смогу добавлять новый функционал в конструкторы дочерних классов?Как-то я сам об этом даже не подумал.Спасибо.Думаю это поможет решит проблему.
>>215126639>Потому что учусь и мне стоит их знать, иначе вечно буду хуйню писать.Хуйню ты будешь писать если не перестанешь дрочить на паттерны.
>>215127566Да, в конструкторе родительского класса. А вот куда добавлять логику у дочерних классов, это вопрос. Но можно и в конструктор и в отдельные методы
Тред не читай, сразу отвечай.Вместо перекрытия и вызова того же самого метода, предок должен вызывать новый абстрактный метод и именно его надо перекрывать в наследнике (паттерн шаблона).А вообще, поебать. Никому нахуй не вперлось ооп в 2020.
>>215127696Каждый должен пару лет жизни подрочить на паттерны, даже если он не имеет никакого отношения к компьютерам. Это важный этап становления личности.
>>215127761>Никому нахуй не вперлось ооп в 2020Двачую братишку! Правда на собесах упорно спрашивают это дерьмо.
>>215127708Суть в том, что у дочерних классов есть и свои дочерние классы.И каждый раз им нужно инициализировать всё больше и больше данных.И дабы не писать тонны кода, я просто вызываю базовые методы инициализации, которые были у родителей.Получается всё хорошо и на вид, и на деле.Но как оказалось - это ошибка, хоть и не очевидная.
>>215127952В том, что нет необходимости рассчитывать на "конвенцию" (все потомки обязаны вызвать метод предка). Какой-то долбоеб может забыть вызвать метод предка и нет никакой возможности проверить статическим анализатором что предок был вызван. В случае с паттерном шаблона ты просто не сконпелируешь класс потомка, пока не определишь новый абстрактный метод.>>215127998Потому что так научили мартыханов из HR. Ну, и ленивый тимлиды иногда спрашивают, потому что в свое время спрашивали их, а выдумывать новые вопросы сложно.
>>215128144Инициализация должна происходить в конструкторе или метод инициализации должен в нем (конструкторе) вызываться. Зачем извне её вызывать? Тем более, что там ещё иерархия какая-то намечается. Классы должны быть самодостаточными, без учета того, что кто-то там должен дергать метод инициализации
>>215128326>Инициализация должна происходить в конструктореВообще-то, нет. Сильно зависит от времени жизни объекта.Если инициализация зависит от других компонент и есть какое-то подобие inversion of control и dependency injection, то конструирование объекта и его инициализация это разные вещи и они должны контролироваться контейнером. Ну, и плюс писать юнит тесты для классов с бизнесс логикой в конструкторе оче сложно.
>>215128326Чтож. Звучит логично.Каждый класс будет инициализировать свои данные в конструкторе и мне не придётся с ними ебаться.Спасибо анон, действительно помог.У меня из головы вылетело то, что конструкторы предков тоже вызываются при инициализации дочерних классов и я вообще про конструкторы забыл.
>>215128773Вот, блять, поэтому ответа в гугле я не нашёл.Но впрочем мне нужно, чтобы объект инициировался в начале своей жизни и в будущем уже мог использоваться.
>>215128259>новый абстрактный методСпасибо анон. Плохо разбираюсь в этом.Придётся потратить время на изучение этой темы.
>>215127475согласен с этим, первое что в голову приходит. Касаемо того, чем плох вызов предка - вероятнее всего ломает полиморфизм
>>215125922 (OP)вот не шаришь ты химию и несешь всякую хуйню и валишь самостоятельные. вызвали предковА у них метод ЗнанияПоХимии не реализован.Ну колхозаны они, какая химия? Ошибка времени выполнения.?Зато реализован метод ДатьПизды. Его и применят после разговора с учителем.
>>215128850>конструкторы предков тоже вызываются при инициализации дочерних классовСам по себе вызывается только конструктор по умолчанию (без параметров). Если у предка есть два конструктора, то тебе надо выбирать какой из них вызвать из наследника. Если ты случайно пропустишь вызов конструктора предка, возможно вызовется не тот, что надо и ты узнаешь об этом только в рантайме. В общем, тот же анти-паттерн.
>>215125922 (OP)>Как я вычитал в гугле - тут на лицо анти-паттерн "Вызов предка", но я не понимаю как от него избавиться.Это типа наследование, иногда полезен иногда и нет, сейчас он используется в некоторых специфических случаях, можешь использовать композицию, создавай независимые классы и вызывай их в основном классе, типа класс становится модульным.
>>215128973class A { void init() { // doSomeCommonShitHere anotherInit(); } abstract void anotherInit();}class B extends A { void anotherInit() { // doMoreShitSpecificToB }}
>>215125922 (OP)ОП пидор, програмирует в своих программах, ебучих программных роботов-киборгов-убийц чтоб они захватили нашу планету. Умри скотина!
>>215128994>вероятнее всего ломает полиморфизмЕсли так подумать - то логично.Я переопределяю метод в дочернем классе, но при этом вызываю базовый метод в переопределённом.Но блять, не писать же гору текста.
>>215129981Ну, чувак.Двач - это не только толпа одичавших долбаёбов, инцилов и пиздолизов.Это ещё и другой народ, который может дать дельный совет.>>215129382Вот выше мне указали на абстрактные классы, которыми я не пользовался, а они, оказываются, мне нужны.Не зря создал тред.
>>215129981И зайдёт какой-нибудь такой же как я анон-дегенерат, почитает и поймёт, что ему нужно что-то изучить, чтобы не создавать тупые треды.
>>215129745можешь по аналогии с этим сделать https://en.wikipedia.org/wiki/Call_super. Просто в родительском классе создаешь абстрактный (либо просто пустой метод) postProcess(), например, и вызываешь его в родительском после или внутри своего инит-метода. postProcess уже переопределяешь в наследниках
>>215125922 (OP)Это не антипаттерн, тут все зависит где он используется и кем.Если ты делаешь так во внешней библиотеке которую используют другие, то это плохо, если делаешь у себя в программе и тем более только ты, то ок.По сути этот функционал скрывается за фабрикой чтобы кто-то другой не мог по ошибке забыть вызвать родительский класс.В реальном проде вообще всем похуй на эти антипаттерн и делают как угодно кроме пары исключений на которые у тимлида стоит.
>>215130367Ну.Я делаю свою супер-пупер-убийцу-всего-на-свете игру на Юнити.Думаю, я могу иногда использовать антипатерны ведь работаю я один.По большей части мой проект - это просто тренировка и практика, где я тестирую новые знания.Тут, я знаю, высмеивают за игры на юнити, но это действительно неплохой вариант вкатиться в программирование, потому что сталкиваешься с ситуациями, которые нужно как-то решать решать.
>>215130594Юнити и программирование это разные вещи.Там все достаточно узко и специфично, если хочешь в геймдев идти на юнити то ок, если просто программистом, то не ок.
>>215130716Тут поспорить не смогу.Ты прав.Но он помог мне освоить списки, словари, разобраться в типах данных. Я выяснил, что String может сильно забивать память и иногда лучше использовать Stringbuilder.Освоил ну как освоил, ознакомился с рефлексией.Базовые знания +- можно получить.
>>215130368А вообще, как сказал >>215130367, на это по большему счет хуй кладут как и на моем теперешнем проекте, так что я бы над таким даже голову не ломал на твоем месте
>>215125922 (OP)>Встал вопрос с одним анти-паттерном - Вызов предка (Call super).>Поясните мне чем он плох? Чо, даже википедию не смог прочесть?the fact that the language itself may not be able to enforce all conditions prescribed on this call is what makes this an anti-pattern.The anti-pattern is the requirement of calling the parent. There are many examples in real code where the method in the subclass may still want the superclass's functionality, usually where it is only augmenting the parent functionality. If it still has to call the parent class even if it is fully replacing the functionality, the anti-pattern is present.Перевожу для безграмотныхАнтипаттерном это становится, ТОЛЬКО ЕСЛИ ТЫ ТРЕБУЕШЬ вызывать родительский метод.И антипаттерном это является потому, что это ты требуешь, а средствами языка заставить это делать не можешь.Т.е. можно написать такой класс-предок, который не вызовет родительский код, И ЧО ТЫ СДЕЛАЕШЬ?
>>215129745Ты ничего не будешь нарушать. Наследование , оно на то и дано, чтобы наследовать поведение, а местами расширить. Делай инициализацию в конструкторе базового класса и наследуй его. Ты будешь обязан вызвать супер в конструкторе наследника.Ты не ломаешь полиморфизм. Он совсем про другое.
>>215130873Я всё понимаю, что на многое закрывают глаза.Но у меня интерес к этому уже есть, хочется почитать/поизучать/попробовать.Люблю программирование.
>>215130929Так, кажется начинаю понимать.Нет ничего страшного в том, что я вызываю родительский метод в переопределённом методе дочернего класса.Страшно то, что базовый метод не вызывается принудительно и его могут забыть?Бля, тогда это всё объясняет.Тут действительно можно использовать абстрактный класс или на край прикрутить интерфейс.
>>215130915Эти слова успокаивают.+ тут ещё и пояснили, что я должен принудительно вызывать базовый метод, чтобы не нарушалась работа класс потому что если не вызвать родительский метод, то весь класс полетит в пизду.
>>215125922 (OP)Схуяли super антипаттерн? Как ты собрался делать переопределение метода из родительского класса, копипастой кода?
>>215131056Можно ещё базу данных и запросы к апи. Из простой модели раздули страшное и непонятное чудовище
>>215131140Ну это логично, если у тебя конструирование класса через методы идёт.должно быть через конструктор
>>215131209Так вот блять в этом и весь юмор.Я и не понимал, нахуя мне копировать то, что уже есть в родительском классе.Если бы не это - на создал бы тред.
>>215130873Тем лучше. Можно единственному изо всей группы ебашить идеальный код и смотреть на других как на говно.
>>215131403Я не особо давно в программирование и то, что для вас очевидно - у меня иногда вызывает вопросы.
>>215130983Понимаю, сам когда-то все это хотел поизучать, но в целом паттерны не лучшая область для изучения, но дело твое. А так: удачи и не выгореть
>>215127761Ты просто макака. В сложном софте единственное вариант не закопаться это организовать программу как взаимодействие классов.
>>215131488Потому что на форумах чуть что - сразу в гугол отправляют, а в гугле в википедии пишут про то, что это антипаттерн и его нужно избегать.А избегая его я затрагиваю ещё ряд антипаттернов.
>>215125922 (OP)Смотри, если ты вызываешь методы предка для реализации СВОЕГО функционала, то это ОК. Т.е. нужно - вызываешь, не нужно - не вызываешь.Но если ты ОБЯЗАН вызвать метод предка, чтобы просто все работало, то это значит, что код неправильно организован, а нужные функции не выделены как положено.
Я если честно нихуя не понял что за строки и категории, но если это какая-то инициализация, то происходить она должна в конструкторе
>>215131728Да, я ОБЯЗАН вызывать метод предка в переопределённом методе наследника.Сейчас мне пояснили как можно избавиться от этой ошибки, стараюсь применить на практике все советы.
>>215131728Сложно представить такую ситуацию, когда не достаточно вернуть методом валидное значение, вероятно метод предка меняет глобальные переменные или состояние инстанса.
>>215131822в конце статьи в вики (английской, само собой) про этот кол супер дан рецепт, как этого избегатьвызываешь из родительского абстрактный метод, который реализуешь в каждом наследнике. не реализовать абстрактный метод в наследнике ты не сможешь
>>215131883Может, там какой-нибудь йоба-алгоритм на два экрана, а наслденики только по-разному готовят входные данные.
>>215125922 (OP)Суть антипаттерна в том, что если тебе для того, чтобы добавить наследника, нужно чтобы этот наследник обязательно вызвал метод предка - значит когда-то этот метод вызвать забудут и все пойдёт по пизде. Тебе надо этот общий обязательный код внести в конструктор, а изменяющуюся (для наследников) часть - в отдельные методы, и уже эти методы оверрайдить в наследниках..
>>215132391Понятно.То есть условно - если я согрешу и у меня будет в проекте этот антипаттерн - он не заруинит проект (я один работаю).Просто, к примеру, антипаттерн "спагетти-код" как раз руинит разработку.
>>215132006Но ведь тогда мне придётся каждый раз писать код.Не проще один раз написать реализацию в родителе и каждый раз использовать её?Это же самая настоящая копи-паста, что тоже антипаттерн.
>>215132520Не заруинит, но лучше пинать себя за каждую такую хуйню. Не важно сколько человек работает, ты сам же можешь потом напороться на эту мину
>>215132006ВСКОРЕ В ПОДНАСЛЕДНИКЕ ТРЕБУЕТСЯ ЭТО НЕМНОГО РАСШИРИТЬ@CALL SUPER — АНТИПАТТЕРН@ЖИДКО ПЕРНУВ КОПИПАСТИШЬ
>>215132862Вот блять ДА.И нахуй это нужно?Один антипаттерн закрывать другим?Не проще пойти по пути менее пиздецового антипаттерна?
>>215132923>>215132862ИТТ уже три раза нопейсали как решить проблему. Даже с примером.Походу, тред иллюстрирует что не всем дано в ойти вкатиться.
>>215132862Дак в чем проблема - в наследнике из главного метода вызываем новый отдельный (можно даже не абстрактный)В поднаследнике его переопределяем и у наследника главный метод будет расширенным.
>>215125922 (OP)Оп, нестрадай хуйней. Программа должна выполнять свою функцию. Какими путями ты этого достигнешь - всем похуй. Устроили тут рефакторинг бля.Мимосеньор
>>215133181То есть ты предлагаешь переделывать наследника, чтобы запилить поднаследника? А с OCP по ебалу не хочешь?Или ты просто предлагаешь единожды спроектировать архитектуру, а от всяких эволюционных моделей отказаться?
>>215133553Ну OCP да, но тут уже изначально проебались, что началась ебля с деревом наследований, надо было использовать делегирование для изменяющейся части.>>215133642Не, ты не понел. Поднаследник ничего не вызывает. Он Наследует основной метод от наследника, но внутри этого метода есть вызов того метода, который у поднаследника свой. Всё расширение в этом самом методе поднаследника.
>>215133807Я тебе говорю про тот код, что этих твоих наследников с поднаследниками в конечном итоге юзать будет. Какой из трёх методов ему вызывать?
>>215133642Мы его будем вызывать через тот интерфейс где метод впервые объявлен. Т.е. метод будет только один.Исходя из того, какого класса объект - будет вызываться метод наследника/поднаследника и т.д. Полиморфизм
>>215126894Ты этому всему научишься со временем на интуиции без всяких книжек, а так ты только будешь свои паттерны пихать туда, куда не следует и не более, пока не отработал 5 лет кодером не забивай этим голову, когда уже будет такая квалификация, чтобы архитектором быть, тогда ты и сам уже будешь всё это знать.
>>215133438Всё он к месту применил, не выёбуйся на дядьку, он небось 10 лет назад уже кодером работал, когда ты под стол пешком ходил.мимомидл
>>215134619>Программа должна выполнять свою функцию. Какими путями ты этого достигнешь - всем почмоки-чмоки.Да, ахуенно
Используй либо шаблон, как писали выше либо делегирование. Передаешь класс который умеет в базовую интциализацию.При делегирлвании проще расширять функционал.
>>215125922 (OP)>>215125922 (OP)Ты бы хоть узнал почему вызов предка антипаттерн сначал. Вызов предка плох, потому что тот кто пишет код ребенка не будет знать, что предок ОЖИДАЕТ, что его вызовут. Вместо вызова предка юзай темплейт паттерн - предок сам себе все иниттит, а попутно вызывает другой метод - вот его-то сабклассы и имплементируют. Таким образом метод предка всегда будет вызван, а сабклассам ПРИХОДИТСЯ имплементировать навязанную им логику.
>>215131872Ну вариантов 2 либо ООП, либо процедурное программирование в стиле с. Второе намного сложнее.
Да, аноны, спасибо.Помогли.Я, конечно, от костылей не избавился (Ибо на Unity сложно реализовать класс через конструктор), но от антипаттерна избавился с помощью абстрактных классов.
>>215139432>потому что тот кто пишет код ребенка не будет знать, что предок ОЖИДАЕТ, что его вызовутотказываться от удобной штуки только из-за того, что кто-то там не заглянет в код родителя или чего-то там не знает, ну это не аргумент - super это простой и удобный инструмент, который экономит кучу времени и защищает от дублирования кода, не увеличивая сложности при этом.
>>215146667Ну, дублирование кода я-таки избежал.Но у меня появилась куча абстрактных методов.Впрочем, с ними стало даже удобнее, ибо уменьшилось число строк кода.