- 1
Про убогость ООП подхода.
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−7
Про убогость ООП подхода.
Итак, вот допустим наследование. Есть всякие там тупые примеры ООП, типа "котик и собачка наследуется от четырехногих" и проч., где подобный бред вполне работает. Но давайте попробуем рассмотреть более интересные ситуации.
Допустим что мы пишем некую игру. В игре есть некое оружие, например там есть огнестрел и дубинки. И мы делаем ружье, которое одновременно и огнестрел и дубинка, т.е. ружьем можно и как палкой уебать, и пальнуть как из револьвера. У родительского класса "огнестрел" есть свойства, типа дальности выстрела, точности, используемых боеприпасов, уровень прочности(износ), вес, наносимый урон при попадании. У дубинки есть свойства длины дубинки, уровень прочности(износ), вес, наносимый урон при ударе. Вес для ружья нам нужен только один, т.е. нет смысла делать два "веса" одному предмету. И огнестрел и дубинка наследуется от родительского класса "объект инвентаря", в общем тут ромбовидное наследование, которое в разных языках решается разными способами. Ну ок, допустим что мы там каким-то образом указали компилятору некоего языка X, что наследовать свойство "вес" надо лишь один единственный раз, как и прочие хрени, которые являются общими для родительского класса "объект инвентаря". Теперь надо решить с прочностью. Не все "объекты инвентаря" в этой игре имеют свойство прочности, есть например какие-то расходные материалы, типа патронов, для которых понятие прочности неприменимо. Использование ружья как дубинки изнашивает его не таким же самым образом, как использование ружья как огнестрела, но при этом слишком большой износ ружья-как-дубинки может настолько повредить его, что как огнестрел его уже и не поиспользовать из-за погнутого ствола. Но использование ружья как огнестрел никак на износ ружья-как-дубинки не влияет, типа это механический износ спускового механизма, износ ствола при стрельбе...
j123123 02.11.2017 04:04 # +2
Короче, если мы хотим от этих двух говен унаследоваться так, как надо по такому вот хитровыебаному условию, надо иметь некий способ чтобы указать то, как правильно эти хрени накладывать, какие общие свойства двух родительских классов будут сведены к одному, какие будут дублироваться (типа "прочность как огнестрела" и "прочность как дубины") и их взаимное влияние(т.е. если ружье сильно раздолбать как дубинку, стрелять из него тупо нельзя).
j123123 02.11.2017 04:05 # +1
https://ru.wikipedia.org/wiki/Ромбовидное_наследование :
> Common Lisp пытается реализовать и разумное поведение по умолчанию, и возможность изменить его. По умолчанию выбирается метод с наиболее специфичными классами аргументов; затем, методы выбираются по порядку, в котором родительские классы указаны при определении подкласса. Однако программист вполне может изменить это поведение путём указания специального порядка разрешения методов или указания правила для объединения методов.
Вот что Lisp животворящий делает!
SemaReal 02.11.2017 04:44 # 0
хорошее, годное ооп у смалтокообразных япов типа рубей (и немножко даже у обжсей)
ынтерфейс лишь контракт на обработку сообщений. сообщения можно отказаться принимать
d_fomenok 02.11.2017 10:04 # 0
# хорошее, годное ооп у смалтокообразных япов типа рубей (и немножко даже у обжсей)
ООП везде одинаковое, хоть это Smalltalk, хоть это C++, хоть это Java, отличаются только их причуды.
Или нет? Кто сможет привести убийственную фичу у Python, Ruby, Smalltalk и докажет их сильное отличие от C#, тот молодец.
SemaReal 02.11.2017 15:42 # 0
Можно юзать ООП даже в языках без ооп (hint: object manager в windows executive):
Просто смалток говорит: "объекту можно послать сообщение, он может его обработать, может форварднуть дальше (делегировать), сохранить итд. Объекта можно спросить: умеет-ли он получать сообщение".
А в несмалтокообразных ЯПах вместо сообщения просто вызывают функцию, которая неявно получает указатель на объект (или явно в питоне). Это позволяет делать перегрузки, но усложняет форвардинг, и менять список поддерживаемого/неподдерживаемого сообщения в рантайме сложнее
https://stackoverflow.com/questions/1143993/what-are-the-schools-of-oop
d_fomenok 02.11.2017 16:21 # 0
# сообщения просто вызывают функцию
Но чем эти два подхода лучше другого?
SemaReal 02.11.2017 17:34 # +5
Технически можно тоже самое сделать в java, просто это будет многобуквенно, не естественно
d_fomenok 02.11.2017 17:52 # 0
Stallman 02.11.2017 18:00 # 0
Вместо
будет
Обычное делегирование. Да, в жабе многобуквенней, но она никогда и не претендовала на краткость.
d_fomenok 02.11.2017 18:04 # 0
Толи дело Сишарпик:
void talk() => cosplay.talk();
SemaReal 02.11.2017 18:10 # 0
ты всех их будешь так писать?
еще раз подчеркиваю!
"Технически можно тоже самое сделать в java, просто это будет многобуквенно, не естественно"
roman-kashitsyn 02.11.2017 18:11 # 0
SemaReal 02.11.2017 18:19 # 0
я, кстати, нифига не уверен что это так уж хорошо
просто показываю какую можно магию делать
а вот в obj-c типизация статическая есть, но там все равно можно спросить у объекта отвечает-ли он на message, и если да то послать
d_fomenok 02.11.2017 18:13 # 0
А что, так бывает?
SemaReal 02.11.2017 18:19 # 0
Вот тебе еще прымер
.
В C# ты тоже так можешь сделать, но понадбится наверное рефлексия.
Понимаеш что тут происходит? когда мне шлют message на который у меня нет ответа (method missing) я просто форварджу его дальше
d_fomenok 02.11.2017 18:37 # +1
Тут вообще плохая архитектура, масса должна быть обычным свойством, а jump должен считать высоту на основе массы
SemaReal 02.11.2017 18:26 # +2
Fike 02.11.2017 18:42 # +6
Хуита. В руби вызов метода это все еще вызов метода, просто создатели обчитались статей с хабра о Правильном ООП и начали называть это пересылкой сообщений, потому что в их представлении именно этот факт и отделяет обычные реализации от Правильного ООП. Технически то же самое можно сделать и на жабе через прокси.
А манки патчинг и дак тайпинг это все еще манки патчинг и дак тайпинг.
d_fomenok 02.11.2017 18:51 # +1
Из Википедии:
К тому же использование такого подхода нарушает принцип инкапсуляции объектно-ориентированного программирования.
SemaReal 03.11.2017 03:29 # 0
Fike 03.11.2017 10:00 # +2
Desktop 22.02.2018 15:52 # 0
g0_1494089131830 22.02.2018 15:52 # −1
Stefan 22.02.2018 15:52 # 0
g0_1494089131830 22.02.2018 15:52 # 0
AnalBoy 18.01.2020 18:42 # 0
Dummy00001 02.11.2017 04:50 # +5
кресты и OOP тут ни причем. ты просто ОО еще пользоватся не научился.
> Ромбовидное_наследование
вообще тут ни причем. читай ООАиД - и учись классы из предметной областы выделять.
и если правильно научишься "классифицировать", тебе уже будет по барабану язык программирования - ОО или не ОО. потому что те же яйца вид с боку. или как классики говорили: наследование это всего лишь синтаксический подсластитель аггрегации.
j123123 02.11.2017 05:07 # 0
ООП просто для этого НЕ ПОДХОДИТ. Оно ограничено. ООП-наследование подразумевает что у чего-то там есть родитель, и "наследник" у родителя все свойства копирует себе, но это часто не нужно. Есть четвероногие, мы наследуем псов от четвероногих. Потом у нас появляются в игре псы-мутанты с 5 ногами, мы хотим унаследовать их от обычных псов, но без унаследования четвероногости. Т.е. скопировать все что есть у псов кроме отдельных кусков, связанных с четвероногостью. Как это решается в ООП наследовании?
j123123 02.11.2017 05:11 # +1
Dummy00001 02.11.2017 05:17 # +3
ночью лень тебе много писать. но еще одна - сопряженная - тема для медитации: поразмышляй на тему отношений/реляций/relationships между классами. и более конкретно над ответом на вопрос: в ОО, что такое реляция? (или: сколькими способами ее можно представить?)
j123123 02.11.2017 05:23 # −2
Требование какой задачи я игнорирую?
Спрашиваю еще раз:
Как мне с этой ООП моделью взять из некоторого одного класса некую одну часть, из некоторого другого класса другую часть? Не унаследовать и то и то целиком, а просто взять там и там куски?
SemaReal 02.11.2017 05:45 # 0
inkanus-gray 02.11.2017 13:58 # 0
Fike 02.11.2017 18:43 # 0
inho 04.11.2017 20:19 # 0
SemaReal 04.11.2017 20:20 # +1
d_fomenok 02.11.2017 10:14 # 0
С таким подходом создатель языка и его пользователи столкнутся с кучей граблей по поводу применимости в данной ситуации этих кусков кода. В ООП это делается намного проще: создай вспомогательный класс и с помощью них реализуй нужные тебе интерфейсы.
Dummy00001 03.11.2017 02:03 # +2
кучи уже понаписали, а времени/мозгов у меня читать все уже нету (мля уже опять ночь).
> > Есть четвероногие, мы наследуем псов от четвероногих. Потом у нас появляются в игре псы-мутанты с 5 ногами, мы хотим унаследовать их от обычных псов, но без унаследования четвероногости.
все зависит от того *чем* 4-ре- и 5-ти- ногие собаки отличаются от друг друга - с точки зрения требований решаемой задачи.
например в графических играх они от друг друга вообще ничем отличаться не будут - кроме номера модели/текстур которыми они будут рисоватся на экране.
та же херня и относительно твоих {свойство "прочность огнестрела" и "прочность дубинки"}. вопрос не в том как словарь русского языка смотрить на эти вещи - а что с ними нужно делать. в большинстве програм которые что-то будут с ними делать все будет намного сложнее - и все в лоб будет своим отдельным классом/интерфейсом, и поверху еще будут стэки эффектов, и все будет считаться скорее всего процедурально. в добавок эти все мелочи еще будут state machine'ами потому что например игры любят это все через effect-over-time делать (т.е. эффект аттаки применяется не мнгновенно, а за, например, 0.5 секунд).
поэтому то твои жалобы на ООП выглядят весьма глупо. почему я и говорил о реляциях. классы/объекты как-то к друг другу относяться. и более того: некоторые реляции приходится описывать своим классом, потому что у реляций (тот же damage в играх) тоже могут быть свойства.
j123123 02.11.2017 05:25 # 0
Наследование — это самая большая провокация в индустрии. Ни в каком моделировании наследования не существует (и в реальной жизни его нет тоже) — ни в электронике, ни в бухгалтерии, ни в политике, ни где бы то ни было еще. Есть лишь одна область, где наследование теоретически встречается — генеалогия (эй, парни, лучше не путать это с гинекологией). Но это не имеет ни малейшего отношения к тому, что называется наследованием в программировании. Все эти многоэтажные иерархии классов только усложняют жизнь программиста, вместо того, чтобы упрощать по своему замыслу.
Fike 02.11.2017 09:54 # 0
SemaReal 02.11.2017 15:17 # 0
Особенно порадовал нахрюк на рефакторинг: в процедурном коде-то никто ничего не рефакторит, там все сразу правильно пишут.
Запишите уже себе на лбу: наследовать нужно интерфейсы (протоколы) а не реализации.
bormand 02.11.2017 08:22 # +3
А я всегда говорил, что наследование - говно (т.к. все пытаются наследовать реализацию, городить уёбищные иерархии и рано или поздно наступают на грабли). Самая сомнительная часть ООП.
А твоя задача даже на обычных языках вполне решается внешними хелперами, интерфейсами, агрегацией и какой-то матерью...
inkanus-gray 02.11.2017 08:38 # 0
bormand 02.11.2017 08:47 # 0
j123123 02.11.2017 10:27 # +2
Разберем ООП применительно к плюсам (в других языках могут быть свои ньюансы):
Плюсовый класс это такая хрень типа структуры(можно наобъявлять там переменных всяких), но с возможностью там объявлять еще функции(которые в данном случае называют методами), и это все (переменные, методы) еще размещается (помечается) в public protected private кусках, в которых различаются права доступа к этим штукам. Protected хрень доступна для классов, производных от данного, public доступна всем, private доступна только членам класса и friend-ам. ОК, а если я хочу сделать помимо public private protected еще одну хрень, специфицирующую доступ, назову ее huekted, которая например будет доступна всем функциям/методам кроме членов класса и friend-ов (хуй знает нахуй это нужно, просто придумал от балды) то что тут можно сделать? Нихуя!
А есть ведь еще и public, private, protected наследование. Почему я не могу добавить еще какой-то способ наследования? Почему нельзя было все это реализовать в максимально общем (кастомизируемом) виде, чтобы помимо public private protected можно было вводить свои принципиально новые модификаторы доступа, придумывать свои хитровыебаные способы отнаследоваться и прочее прочее?
j123123 02.11.2017 10:34 # 0
d_fomenok 02.11.2017 10:37 # +1
Очень хорошая точка зрения. А теперь приведи пример, где бы тебя это спасло.
j123123 02.11.2017 10:43 # −2
d_fomenok 02.11.2017 10:35 # +1
# то что тут можно сделать? Нихуя!
Т.е. С++ не нужен, потому, что ты не можешь на нём сделать фичу, не имеющую практического применения?
j123123 02.11.2017 11:05 # 0
d_fomenok 02.11.2017 11:05 # +1
Но зачем тебе больше?
j123123 02.11.2017 11:11 # 0
Stallman 02.11.2017 11:15 # +1
/thread
inkanus-gray 02.11.2017 11:35 # +2
dxd 03.11.2017 14:49 # 0
d_fomenok 02.11.2017 11:34 # 0
Предложи ещё, но чтобы они были полезны.
j123123 02.11.2017 12:16 # 0
Или сделать public2. Методы, объявленные как public2 не могут в своем коде вызывать методы данного класса, которые public или public2 кроме ситуаций с рекурсией.
В такой способ мы говорим программисту, что public методы только извне вызывать разрешено.
d_fomenok 02.11.2017 12:41 # 0
# В такой способ мы говорим программисту, что public методы только извне вызывать разрешено.
Я вот не понимаю, это ограничения помогут как-то сделать более понятный код, помогут при составлении документации, благодаря им ты сможешь избежать уязвимостей? Что тебе это даст?
j123123 02.11.2017 13:02 # −2
А чем помогают ограничения, накладываемые private? Что они дают? Давайте все методы делать public, настоящие цари ж лучше компилятора знают, что им там можно и чего нельзя откуда вызывать.
Таким ограничением мы декларируем что вот функции эти - внешние и их можно дергать только извне класса - они не предназначены для внутреннего использования внутри классов. Интерфейс для взаимодействия с объектом из внешнего мира нужен только как интерфейс, и не должен внутри как-то сильно задействоваться в самой логике класса, т.е. пусть он просто вызывает какие-то внутренние функции или что-то там сам по себе делает. Изнутри он вызываться не должен т.к. нужен именно для взаимодействия с внешним миром
d_fomenok 02.11.2017 13:17 # 0
Дают они очень важную вещь: скрыть детали реализации от внешнего мира.
А вот то, что ты предлагаешь (скрывать публичных членов от самого себя) - глупость.
j123123 02.11.2017 13:26 # 0
А зачем их скрывать? Можно просто не обращать внимания, т.е. тупо НЕ ВЫЗЫВАТЬ те методы, которые являются деталями реализации.
> А вот то, что ты предлагаешь (скрывать публичных членов от самого себя) - глупость.
А почему глупость? Я вот может хочу, чтобы публичные методы годились только для вызова приватных методов, т.е. считаем что все публичные методы это такая хрень, которая что-то там приватное вызывает, а вызывать публичные методы из приватных и публичных нафиг не надо.
Всю логику выносим в приватные методы, а публичные просто вызывают приватные. Кроме того, можно придумать несколько слоев приватных методов. Например, первый слой приватных методов может вызывать методы из первого слоя приватных методов, и методы из второго слоя приватных методов. А приватные методы из второго слоя только такие же методы могут вызывать, или методы еще более глубокого слоя. И чем глубже слой, тем ближе к "железу" работает тот метод.
roman-kashitsyn 02.11.2017 14:00 # 0
Не нужны для этого никакие хитрые изменения прав доступа, просто вкладываешь объекты разного уровня друг в друга.
j123123 02.11.2017 23:26 # −1
Если вкладывать объекты разного уровня друг в друга, это поможет мне поставить ограничения вида "public метод уровня N имеет доступ только к public методам уровня N и N+1, но не более низкого уровня"?
Вот например, пишем допустим хрень для создания-удаления файла. Функции типа open() fstat() lseek() unlink() и прочая такая хрень - public. Им можно обращаться к слою функций, которые абстрагируются вообще от всей питушни, и совершенно не предполагают прямой доступ к жесткому диску. Ну там может быть FUSE или подмонтированная NFS или SMB хрень. В одном из случаев этот слой доступных из юзерспейса функций будет взаимодействовать с каким-то уровнем драйвера ФС. Рассмотрим такой случай
Уровнем ниже будет питушня ФС. Например, если это какой-то там EXT3 то это журналируемая ФС и она там пишет в внутренний журнал какую-то питушню при удалении-создании файлов и прочее, управляет свободными блоками ФС, делает какие-то там манипуляции со структурами данных, специфичных для конкретной ФС. В общем эта какая-то внутренняя питушня для конкретной ФС, которую нельзя вызывать из юзерспейсного слоя, потому что можно что-то легко запороть. Из юзерспейсного слоя можно вызывать только питушню open() read() write(), которая уже у себя делает вызовы более низкого уровня абстракции.
А еще слоем ниже будет какая-то питушня, которая отпавляет ATA команды к жесткому диску на запись каких-то там блоков в какие-то там области, и эти ATA команды можно вызывать только из слоя на один выше т.е. из слоя драйвера ФС. Из слоя, где разрешено вызывать open() read() write их вызывать нельзя. Т.е. есть строгий набор правил, из какой питушни что можно, и что нельзя делать
roman-kashitsyn 02.11.2017 23:45 # 0
Да. Именно так я обычно и структурирую приложения. Для этого даже ООП никакого не нужно.
d_fomenok 02.11.2017 15:27 # 0
Не надейся на чужую порядочность. Для этого и создан private.
# Я вот может хочу
Хотеть не вредно (с).
# а вызывать публичные методы из приватных и публичных нафиг не надо
Тебе не надо - не вызывай, в чём проблема? Тем более это почти никогда не требуется, разве что в конструкторах.
j123123 02.11.2017 23:01 # 0
Вот я тоже на чью-то там порядочность не надеюсь, и создаю особые private2 из которых нельзя вызвать public
> Тебе не надо - не вызывай, в чём проблема?
Вот правильно, давайте тогда и private уберем, чтоб все public было. Если кому-то не надо что-то там вызывать, пусть не вызывает.
d_fomenok 03.11.2017 13:29 # 0
Это никакая не порядочность, это попытка спасти самого себя от свой глупости. Себя надо спасать только от глупости других, а не от своей.
# Вот правильно, давайте тогда и private уберем, чтоб все public было. Если кому-то не надо что-то там вызывать, пусть не вызывает.
Ты вообще понимаешь, что ты поехавший. Не я поехавший, не он поехавший, а ты?
Приватные члены созданы для сокрытия логики реализации, публичные - для проверок данных извне. Ты хочешь такой модификатор, которым ты хочешь запретить САМОМУ СЕБЕ из логики вызывать другую логику с защитой. Что ты этим добьёшься? На небе появится радуга, а на ней будут скакать анимешные девочки на розовых пони?
vistefan 03.11.2017 10:23 # 0
j123123 03.11.2017 11:24 # 0
Начнем с того, что обычные публичные приватные я не предлагал менять, я предлагал создавать новый вид публичных2 и приватных2 методов, для которых подобные ограничения можно сделать.
Моя претензия к всей этой ерунде с публичными приватными и защищенными методами класса заключается в том, что это всего лишь какой-то частный случай, заложенный на уровне стандарта самого языка, т.е. язык не позволяет добавлять какие-нибудь private2 виды методов, для которых работают какие-то иные правила доступа. Т.е. на мой взгляд вся подобная ерунда должна быть не захардкожена (типа вот есть ключевое слово public - там такие-то правила для таких методов, private - такие-то правила...), должна быть возможность самому свои типы методов делать, самому придумывать всякие произвольные правила для них.
vistefan 03.11.2017 11:41 # +1
Предлагаешь-то ты ввести ещё более частные случаи, у которых потенциально ещё меньше юзкейсов.
Кашицын тебе ж сказал, ты нахуя в ситуации, где надо не наследование, а что-то другое, хочешь использовать наследование, и жалуешься, что наследование плохое? Тут то же самое, только с областями видимости.
Ты вот там приводил пример со слоями методов. Это ты предлагаешь, чтобы один объект был многослойным? Чтобы в пределах одного объекта какие-то его члены имели или не имели друг к другу доступ сложным образом? Это идиотизм, ты огребёшь кучу бойлерплейта и сложнейшую документацию. Кроме того, ты вряд ли придумаешь красивый синтаксис для этого. Не числами же слои обозначать. Стало быть, заворачивать в какие-нибудь обертки, нижние слои завернуты в более верхние. Ну и чем это отличается от где надо -- заворачивания объекта в объект, где надо -- наследования.
---> см. далее
vistefan 03.11.2017 11:41 # +1
Как уже говорили чуваки, уметь выделить из задачи суть, и понять, какие абстракции потребуются -- отдельная задача. Иногда однотипные для русского языка или человеческой психики сущности совсем не имеют общего в реализации, и какого бы хуя им быть родственниками в ООП тогда.
Короче, присмотрись к существующему ООП, и представь, что оно и есть набор тех самых кирпичиков, из которых ты можешь построить всё, что хочешь для частного случая.
Скорее всего, так и есть.
j123123 03.11.2017 12:57 # 0
Можно вообще одним public ограничиться, и никакие private нафиг не нужны. Ничего фундаментального в этом говне нет и быть не может. Так что если исходить из позиции "если этим говном можно и ограничиться, то другого не надо" то давайте вообще все нахер выкинем, оставим только public
j123123 03.11.2017 14:19 # 0
Я считаю что никакой это не идиотизм. Не нравится - не пользуйся. Возможность доопределять новые фичи ЛУЧШЕ чем отсутствие такой возможности. Эта хренота с классами может быть расширена только запатчиванием самого компилятора, т.е. это говно встроено в само ядро языка, и доопределить новые спецификаторы доступа нельзя вообще никак. Нельзя придумать новый способ наследования. Нельзя добавить новые языковые сущности, помимо классов, структур.
Ведь по-хорошему, всю эту хрень с классами, все эти варианты наследования, это все можно реализовать как некую компилтайм-библиотеку, добавляющую эти конструкции. Типа вот есть чистая сишка, подключаем какую-то библиотеку, и вот в сишке уже есть классы. Подключаем еще библиотеку - и вот лямбды появились. Еще одну библиотеку подключили - добавились констэкспры. И так далее. Но таких механизмов нет, да и реализовать их поверх сишного говносинтаксиса будет затруднительно(если вообще возможно), тут разумеется нужна гомоиконность с нормальными макросами т.е. возможностью легко и удобно обрабатывать код самого себя и трансформировать его произвольным образом.
roman-kashitsyn 03.11.2017 14:34 # +1
j123123 03.11.2017 15:10 # 0
vistefan 03.11.2017 14:42 # 0
Не припонмю, что ты писал на ГК раньше, но почти уверен, что ты нигде не работаешь, не имеешь опыта поддержки чужого кода и целыми днями пишешь синтетические хелоуворлды.
j123123 03.11.2017 15:15 # 0
У меня нет сейчас обычной работы (такой, где надо было б каждый будний день ходить в офис и какой-то там хренью заниматься) но вообще я работаю над кое-чем. Опыт поддержки чужого кода у меня есть. Мне вот например недавно в Киеве предлагали постоянную работу с з.п. 3000$ в месяц, но я отказался. Постоянную работу мне найти несложно, просто мне это нафиг не надо
vistefan 03.11.2017 15:20 # +4
Я понял, спасибо.
j123123 03.11.2017 15:21 # 0
inkanus-gray 03.11.2017 15:23 # 0
http://lurkmore.to/_/61475
roman-kashitsyn 02.11.2017 13:18 # 0
Я могу захотеть запретить вызывать публичные методы из приватных, к примеру, когда я пишу класс для коммуникации потоков, и (почти) все публичные методы захватывают локи, а приватные работают в предположении, что лок уже взят.
Но и для этого использовать private/public — говно, потому что локов может быть больше одного. Уж лучше использовать специализированные инструменты
j123123 02.11.2017 13:27 # 0
См. мое предыдущее предложение про слои методов.
roman-kashitsyn 02.11.2017 13:57 # 0
Зачем мне на него смотреть? Я описал ситуацию, когда твои слои могут выглядеть как что-то полезное, но на самом деле всё равно говно по сравнению с алтернативами.
SemaReal 02.11.2017 15:34 # 0
Это вообще совсем никак не относится к ООП.
Desktop 18.01.2020 19:04 # 0
Бери язык, в котором есть кое-что ещё.
https://docs.racket-lang.org/reference/createclass.html#%28part._clmethoddefs%2 9
Desktop 18.01.2020 22:07 # +1
https://stackoverflow.com/questions/29379758/in-rackets-class-system-what-do-augment-overment-augride-etc-do
To clarify the difference between overriding and augmentation, when an overridden method is called, the overriding implementation is executed, which may optionally call the superclass's implementation via inherit/super. In contrast, in an augmented method, the superclass's implementation receives control, and it may optionally call the subclass's implementation via inner.
Песдец какой-то !!111
HoBorogHuu_nemyx 18.01.2020 22:09 # 0
Desktop 18.01.2020 22:13 # +1
Desktop 19.01.2020 01:21 # +1
выведет
200
400
gostinho 19.01.2020 01:35 # 0
Koko 19.01.2020 01:44 # +1
Desktop 19.01.2020 01:51 # 0
Koko 19.01.2020 01:44 # +1
HoBorogHuu_nemyx 18.01.2020 22:12 # 0
Урок домоводства. Учительница:
–— Сегодня мы будем выполнять выворачивание канта наизнанку. Тема сложная, поэтому не отвлекайтесь.
—– Марья Ивановна, это что же получается, моральный закон над нами и звёздное небо внутри нас?
gostinho 18.01.2020 22:33 # 0
HoBorogHuu_nemyx 18.01.2020 22:43 # +2
https://ru.wikipedia.org/wiki/Кант_(элемент_одежды)
https://ru.wikipedia.org/wiki/Кант,_Иммануил
Я даже видел в интернетах срач на тему, можно ли вывернуть кант. Оказывается, можно. Есть специальный крючок из проволоки для выворачивания канта:
https://www.nadel.ru/upload/iblock/7f3/Prym611346.jpg
Что же касается, второй части анекдота, она восходит к цитате Иммануила Канта: «Две вещи наполняют душу всегда новым и всё более сильным удивлением и благоговением, чем чаще и продолжительнее мы размышляем о них, — это звёздное небо надо мной и моральный закон во мне». В оригинале она звучала так: «Zwei Dinge erfüllen das Gemüt mit immer neuer und zunehmender Bewunderung und Ehrfurcht, je öfter und anhaltender sich das Nachdenken damit beschäftigt: Der bestirnte Himmel über mir, und das moralische Gesetz in mir».
vistefan 03.11.2017 10:14 # 0
В динамическах языках -- понятно куча рантайм проверок, поэтому в том числе дорогая абстракция, а в языках типа C++ это реально какие-то "защищенные" области (памяти?), у одного нет права доступа к другому, или это просто компилятор смотрит, не нарушил ли программист в коде какие-либо полномочия?
Что будет, если в крестах написать класс, который в одном из своих методов возвращает другой свой private метод как функцию, а ты во внешнем коде получаешь эту ссылку и пытаешься вызвать?
(Возможно, я сейчас объявил своё глубочайшее непонимание ООП.)
inkanus-gray 03.11.2017 10:21 # +2
Как мы на этапе выполнения проверим, откуда вызван метод? Компилятор должен в преамбулу метода втыкать код проверки и таблицу адресов памяти, из которых разрешён вызов? Но это получится уже динамическая питушня.
gost 18.01.2020 19:37 # +2
Кстати, в «Винде» именно так сделан «Control Flow Guard»: https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard.
HoBorogHuu_nemyx 18.01.2020 19:45 # 0
Можешь привести реальный пример ассемблерного выхлопа cl /guard:cf test.cpp?
gost 20.01.2020 07:24 # 0
Этот самый «__guard_dispatch_icall_fptr» на самом деле является синонимом ntdll!LdrpDispatchUserCallTarget и выглядит так:
gost 20.01.2020 07:29 # 0
*fxd
bormand 20.01.2020 10:07 # 0
gost 20.01.2020 17:08 # 0
Конпелятор же не знает, что в эту «f» могут передать. Может, её вообще из дллки будут дёргать. Вот в «Microsoft» и нашли довольно элегантный выход.
gostinho 20.01.2020 17:09 # 0
SemaReal 02.11.2017 15:30 # 0
не нужно наследовать реализацию
gost 20.01.2020 17:09 # 0
Зачем наследование реализации является обязательным для ООП?
Много реализация наследуется.
Много UML-диаграмма вращается.
gost 20.01.2020 17:10 # 0
О. СёмуРеал забанили?
HoBorogHuu_nemyx 20.01.2020 17:18 # 0
gost 20.01.2020 17:19 # 0
Desktop 20.01.2020 22:14 # 0
HoBorogHuu_nemyx 20.01.2020 22:19 # 0
gostinho 20.01.2020 17:35 # +1
HoBorogHuu_nemyx 20.01.2020 17:47 # 0
Зачем забанили СёмуРеал? Зачем? Зачем?
Koko 21.01.2020 02:47 # 0
gostinho 20.01.2020 17:19 # 0
Koko 21.01.2020 02:41 # 0
Koko 21.01.2020 02:41 # 0
d_fomenok 02.11.2017 10:10 # +1
# псы-мутанты с 5 ногами
Так унаследуй их от n-ногих
А вообще, достаточно одного класса для всех видов крипов.
d_fomenok 02.11.2017 10:19 # 0
Возьми и втуль, чем тебе ООП то мешает?
SemaReal 02.11.2017 04:39 # 0
нарисуй-ка класс диаграмму.
Пока я вижу что можно сделать абстрактный метод у интерфейса IУёбыбл (родителя у всех, кем можно уебать)
метод назвать isМожноУебать()
который у дубинки будет всегда true, а у огнестрела -- функцией от количества уёбанных раз (потом ружжо сломается)
SemaReal 02.11.2017 04:42 # 0
интерфейс IУёбыбл можно удалить из цепочки наследования как только сломается ружье
if item is IУёбыбл
либо
if item.acceptsMessage(уебать)
тогда item.уебать()
else
print "извини чувак, ЭТИМ уебать нельзя"
j123123 02.11.2017 04:59 # 0
Можно не суметь стрелять огнестрелом аж по трем причинам - износился огнестрел (типа там спусковой механизм раздолбался). Износилась дубинка (ствол погнули, когда кого-то уебывали). И нет патронов.
nixel 02.11.2017 09:17 # +1
j123123 02.11.2017 11:51 # −4
Тогда ж будут виртуальный методы, будет создана таблица виртуальных методов для такого класса. Что вообще говоря нафиг не нужно для решения той мелкой задачи. Можно все решить статически, без всей ерунды. Тут не нужно позднее связывание
inho 02.11.2017 19:41 # 0
Ахахахахахахахахах бляяяяя
d_fomenok 02.11.2017 10:18 # +2
Какой текст, какие слова!
И чем же ты предлагаешь его заменить?
А теперь покажи изумлённой публике, как бы ты это сделал без ООП подхода, используя свой аналог.
roman-kashitsyn 02.11.2017 10:32 # 0
В твоей задаче я поступил бы примерно так: каждый предмет обладает набором свойств: вес, износ, размеры, изображение, тип патронов и т.п. Для каждого предмета также можно получить список доступных с ним действий (да, действия — это значения, а не методы). Действия можно применять к паре объектов и изменять их нужным образом. Например, Hit.apply(дубина, враг), Fire.apply(дубина, враг), Load.apply(пушка, патроны_нужного_калибра). Поскольку действия конструируют пользователи в рантайме, не все из них будут валидны, на этапе компиляции недопустимые комбинации не поймаешь. Можно добавить Action.canApply, чтобы показывать пользователю жирный крестик, когда но пытается зарядить гранатомёт патронами девятого калибра.
Это очень базовая ограниченная модель. Кстати, объекты часто определяют в каком-нибудь скриптовом языке (или просто текстовом файле), который используется движком. Указание объекта в качестве простого набора атрибутов в таком случае гораздо проще и удобнее, чем сложные схемы наследования.
SemaReal 02.11.2017 15:34 # 0
А если у меня все классы final, то я не использую ООП?
roman-kashitsyn 02.11.2017 15:57 # +6
Кмк, сама концепция класса и наследования ущербна. Что по-настоящему нужно, так это модульная система,
абстрактные типы данных и интерфейсы модулей. Наследование реализации в OOP-стиле — это убожество.
Имхо, близкая к идеальной система организации кода — это ML-style модули с first-class modules (т.е. когда можно создавать оперировать объектами модулей, например, складывать модули с одинаковым интерфейсом в коллекции).
Отвечу на твой вопрос: если у тебя все классы final, то можно найти взаимно-однозначное соответствие между твоим "OOP"-кодом и модульной системой, похожей на ML.
Классы будут соответствовать типам, объявленным в модуле, публичные методы — интерфейсу модуля, приватные методы — деталям реализации модуля.
d_fomenok 02.11.2017 16:23 # +1
Я после неё боюсь слова "модуль". Мне страшно представить, во что может превратиться C++20 (если введут модули), хоть он мне и не нужен.
roman-kashitsyn 06.11.2017 16:45 # +1
"Модуль" — слово довольно безобидное. Я вот опасаюсь слова "функтор", поскольку в разных коммьюнити оно означает совершенно разные вещи:
1. Термин из теории категорий
2. Класс типов Functor из Haskell/Idris/...
3. "Функциональный объект" в C++, т.е. класс с перегруженным operator()()
4. Модуль в ML, параметризованный другим модулем (т.е. по сути функция на модулях)
bormand 04.11.2017 15:27 # −1
roman-kashitsyn 04.11.2017 21:19 # +2
Desktop 22.02.2018 15:45 # 0
- очень нравится, как сделано в Racket (и, возможно, в остальных схемах).
(provide blabla)
g0_1494089131830 22.02.2018 15:45 # 0
Stefan 22.02.2018 15:46 # 0
g0_1494089131830 22.02.2018 15:46 # 0
Stefan 22.02.2018 15:46 # 0
g0_1494089131830 22.02.2018 15:47 # 0
roman-kashitsyn 22.02.2018 17:05 # 0
А что там такого сделано? Почитал доку, там вроде всё довольно примитивно. Один файл — один модуль, есть явные списки экспорта, но нет явных списков импорта. Непонятно, как делать локальные алиасы модулей.
Детский сад по сравнению с ML. Даже в Haskell лучше.
Или я чего-то не понимаю?
g0_1494089131830 22.02.2018 17:05 # 0
Desktop 22.02.2018 17:45 # 0
SemaReal 22.02.2018 18:29 # 0
Очень хорошая идея, в полностью процедурных подходах ее тоже уважают
g0_1494089131830 22.02.2018 22:23 # 0
Her 02.11.2017 13:01 # 0
subaru 02.11.2017 14:41 # 0
roman-kashitsyn 02.11.2017 14:46 # +6
inkanus-gray 02.11.2017 14:56 # +12
Her 02.11.2017 15:35 # 0
3.14159265 02.11.2017 17:11 # +5
>доказывать кому-то ущербность ООП
inkanus-gray 02.11.2017 17:33 # +1
SemaReal 02.11.2017 17:37 # 0
inkanus-gray 02.11.2017 17:40 # 0
И чуть не забыл: Hurd не нужен.
d_fomenok 02.11.2017 17:45 # −1
А ещё Linux это ядро, а FreeBSD это операционная система.
SemaReal 02.11.2017 18:31 # +1
Linux-based OS vs FreeBSD.
d_fomenok 02.11.2017 18:59 # 0
Ты серьёзно думаешь, что любой дистрибутив Linux лучше FreeBSD?
SemaReal 03.11.2017 03:26 # 0
d_fomenok 03.11.2017 13:33 # 0
Я серьёзно думаю что существующего ООП в Сишарпике достаточно, что бы красиво сделать всё, что я хочу.
SemaReal 03.11.2017 15:41 # 0
Тем не менее у тебя парадокс балба
vistefan 03.11.2017 17:37 # 0
Что за ниша? Лучший объекто-ориентированный си-подобный язык для платформы .NET под Windows? Тесновато.
SemaReal 03.11.2017 17:40 # +3
Понятно же что я сравнил его с жабой, и конечно жаба хуже
vistefan 03.11.2017 17:47 # +1
SemaReal 03.11.2017 17:51 # 0
А C# бывает и за пределами MS: Например Xamarin. А Xamarin же единственный способ шарить логику между аппликухами под IOS и Android не трогая вонючее говно типа javascript
roman-kashitsyn 03.11.2017 17:55 # +2
Не все могут себе это позволить, но связка "ядро на C++ + нативный гуй" неплохо работает.
SemaReal 03.11.2017 18:01 # 0
Тем более что ios у нас на arm, а android бывает на mips, x86/atom и тоже arm.
У ябла clang, а у андроида наверное gcc, да?
Так что писать придется очень осторожно: подразные компиляторы и разные платформы
roman-kashitsyn 03.11.2017 18:15 # +2
Не знаю, про какую бизнес-логику в приложениях ты говоришь, вся бизнес-логика не сервере, клиенты в основном качают из сети, кэшируют и рисуют формочки.
SemaReal 03.11.2017 18:18 # 0
Например, в которых ты можешь составить заявку, и она отошлется когда будет связь с Инетом, и такое приложение должно ее валидировать, например?
Или ты не видел приложений которые имеют локальную БД (CoreData в IOS, sqlite в android) и что-то по ней ищут?
roman-kashitsyn 03.11.2017 18:22 # 0
Валидировать заявки на сервере тоже надо.
Если сервер написан на C++, то вообще сплошной вин.
Ты, видимо, хороших либ для C++ не видел.
SemaReal 03.11.2017 18:30 # 0
Потому что LINQ, например) Или потому что рефлексия упрощает ORM.
Но речь была не об этом, а о бизнес логике
>>Валидировать заявки на сервере тоже надо.
конечно.
>>Если сервер написан на C++, то вообще сплошной вин.
Да, но обычные люди скорее напишут бекенд на C#, чем на С++.
Конечно, если они не Гугл, Фейсбук или Яндекс. Я говорю про обычных людей.
>>Ты, видимо, хороших либ для C++ не видел.
Обычно нужно выбирать максимально высокоуровневый инструмент из всех возмжных, ты согласен?
C# более высокоуровневый, в нем сложнее выстрелить себе в ногу, да и программисты дешевле)
bormand 03.11.2017 18:36 # 0
Если структура базы не меняется после конпеляции - разницы особо нет, просто без рефлексии будет лишний шаг при сборке проекта.
SemaReal 04.11.2017 14:03 # 0
bormand 04.11.2017 14:04 # 0
Ага.
SemaReal 04.11.2017 14:06 # 0
причем это еще и будет работать во много раз быстрее:)
Ну всё равно всякую хуйню про "скидка 23 процента если чел из города КоньКолодезь" и "длина фамилии не больше 10 буков" в общем случае лучше писать на c#, чем на С++
Хотя такие штуки вообще лучше выносить в какие-нить таблицы
inho 04.11.2017 20:22 # 0
vistefan 03.11.2017 17:57 # +1
SemaReal 03.11.2017 18:02 # 0
Если бы было две реализации (открытая и не очень) SDK и VM под Linux, Windows и Mac (как это есть у жабы) то было бы в тыщу раз круче.
Я думаю многие перешли бы на C# с java.
d_fomenok 04.11.2017 15:57 # −2
Он лучший во ВСЕХ нишах. На нём можно писать под что угодно, под телефоны, под древние игровые приставки, операционные системы, приложения рабочего стола, веб-программирование.
gost 05.11.2017 10:12 # −2
d_fomenok 07.11.2017 16:47 # 0
А теперь докажи, что есть язык, который лучше Сишарпика и при этом под все платформы, на которых можно запустить Сишарпик (т.е. просто под все существующие платформы)
subaru 07.11.2017 16:54 # −1
SemaReal 07.11.2017 17:22 # 0
больше полезных идиом, литералов, операторов, сахара
subaru 07.11.2017 17:29 # +2
SemaReal 07.11.2017 17:33 # 0
есть просто такие вещи которые однозначно полезны
например, сахар для аксесоров/мутаторов или вывод типов или генерики в рантейме
gost 07.11.2017 17:36 # +1
vistefan 03.11.2017 10:39 # +3
AnalPerOral 02.11.2017 18:59 # +2
Всех пытаются пересадить на "PHP7" с расширением "mysqli_*"; я же до сих пор пишу под "PHP5" с расширением "mysql_*", и при этом все довольны (особенно клиенты, которым, в целом, похуй, как работает, лишь бы работало). В случае, если требуется миграция на "PHP7", я просто подключаю готовую библиотеку с функциями-обёртками для "MySQL", и всё заебца.
По сути, объектно-ориентированный подход (а точнее - троебучий MVC) является всего лишь одним из агрегатных состояний того языка программирования, в рамках которого применяется. Мне этот кипяток, бурлящий лишними файлами, директориями, ключевыми словами и т.д., весьма неприятен; я предпочитаю процедурный подход комнатной температуры.
Her 02.11.2017 19:18 # −1
AnalPerOral 02.11.2017 19:21 # +4
inho 02.11.2017 19:43 # −1
inho 02.11.2017 21:01 # +1
SemaReal 03.11.2017 03:27 # +1
d_fomenok 03.11.2017 13:37 # −1
А теперь представь, какого размера будет index.php у более-менее крупного проекта.
SemaReal 03.11.2017 15:29 # +1
Тогда лучше разбить на index2.php и index3.php
inkanus-gray 03.11.2017 15:37 # +3
Или вообще так: govnokod23477.php, govnokod23478.php, kabinka25723.php, kabinka1659.php.
SemaReal 03.11.2017 18:05 # −1
это удобно
1024-- 03.11.2017 18:46 # −1
AnalPerOral 03.11.2017 19:56 # 0
SemaReal 04.11.2017 14:12 # +2
Добавить страницу очень просто. Никакие MVC и иже с ними такой гибкости не дают.
ахахахахахахаххаха
bormand 04.11.2017 14:15 # +2
... а также все необходимые стили и скрипты для фронтенда.
SemaReal 04.11.2017 14:19 # +3
А скрипты для фронтэнда тоже можно подключать. Например, страничка может выглядеть вот такт
<SCRIPT LANGUAGE=JavaScript SRC="jquery.js"></SCRIPT>
<SCRIPT LANGUAGE=JavaScript SRC="jquery.ui.js"></SCRIPT>
<SCRIPT LANGUAGE=JavaScript SRC="carousel.js"></SCRIPT>
<SCRIPT LANGUAGE=JavaScript SRC="bdccbcfef4526.js"></SCRIPT>
<SCRIPT LANGUAGE=JavaScript SRC="stranitsa_pokupok.js"></SCRIPT>
<SCRIPT LANGUAGE=JavaScript SRC="script.js"></SCRIPT>
Главное тут не перепутать порядок подключения включая нужные скрипты в каждую страничку
Koko 19.01.2020 00:08 # 0
HoBorogHuu_nemyx 19.01.2020 00:10 # 0
HoBorogHuu_nemyx 19.01.2020 00:42 # +1
gostinho 19.01.2020 00:46 # 0
gostinho 19.01.2020 00:57 # +1
HoBorogHuu_nemyx 19.01.2020 01:05 # +1
Koko 19.01.2020 01:50 # 0
SemaReal это barop aka Roskomgovno, сейчас сидит под гостем. Возможно Stallman тоже его файка.
gostinho 19.01.2020 10:55 # 0
про него и речь
Desktop 20.01.2020 22:18 # 0
Koko 21.01.2020 04:03 # 0
HoBorogHuu_nemyx 21.01.2020 14:48 # 0
Fike 04.11.2017 00:42 # 0
vistefan 03.11.2017 10:41 # −2
2. Скольким программистам ты испортил жизнь, вынуждая их поддерживать твои процедурные write and throw проекты без MVC?
Либо ты сайтист-визиточник, но что тогда ты делаешь одиннадцать лет?
Странно всё это.
SemaReal 03.11.2017 15:29 # 0
SemaReal 04.11.2017 20:26 # 0
roman-kashitsyn 04.11.2017 21:13 # 0
п.с. минуснул не я.
SemaReal 04.11.2017 21:26 # 0
roman-kashitsyn 04.11.2017 22:50 # 0
inho 04.11.2017 23:20 # 0
roman-kashitsyn 04.11.2017 23:31 # +4
inho 04.11.2017 20:25 # −2
inho 02.11.2017 19:33 # +1
Vindicar 04.11.2017 11:56 # 0
Есть у меня привычка использовать protected вместо private, просто потому что я никогда до конца не уверен, что потом не придется на базе текущего класса создавать иерархию.
Это совсем плохо или жить можно?
roman-kashitsyn 04.11.2017 12:44 # +4
Если не уверен, делай всё private. Классы для создания иерархий должны проектироваться специальным образом, а не когда вздумается. Т.е. если вздумается, всё равно рефакторить придётся. private, вероятно, будет наименьшей из проблем.
bormand 04.11.2017 13:43 # +2
Как мне кажется, иерархии вообще нинужны.
В любой иерархии смешиваются 2 концепции - няшное наследование публичного интерфейса и сомнительное наследование реализации. А из-за наследования реализации:
1) растёт связность между классами;
2) реализация размазывается тонким слоем по всей иерархии, её становится сложно понять;
3) в классах накапливается мусор - поля и методы, которые напихали про запас или ради реализации соседних классов;
4) начинается херня в духе "а от чего мне наследовать ружьё, чтобы прикрутить его в иерархию?"
Поэтому, имхо, в иерархии стоит объединять только интерфейсы. А общие куски реализации лучше прикручивать чем-нибудь типа mixin'ов (аля CRTP), а не совать в "базовый класс".
roman-kashitsyn 04.11.2017 14:30 # +1
1. Собрать класс из микс-инов, часто с CRTP, никакая динамическая диспетчеризация тут не нужна
2. Реализация интерфейса, как правило, через Non-Virtual Interface Idiom и общей логикой (проверки пред- и пост- кондишенов) в "интерфейсе".
subaru 04.11.2017 16:57 # −1
Ололо, кто-то реально это делает.
Desktop 18.01.2020 18:42 # 0
- а потом назвать это дело аспектами. Дело хорошее, но как-то на практике всё упирается в то, что сделать грамотный и универсальный mixin посложнее, чем решить вопрос, "а от чего мне наследовать ружьё"
SemaReal 04.11.2017 14:02 # +2
"Проектируйте наследование явно или запрещайте его".
Сделать класс, который можно наследовать не превратив его в говно -- тяжкий труд. Нужно очень четко понять какие методы можно открыть, и какая у них должна быть политика оверрайда (вызов super перед/после/никогда).
А идеале 99.9% твоего проекта должны быть финальными и не поддерживать наследование.
Наследовать надо интерфейсы, а не классы.
1024-- 04.11.2017 20:17 # 0
SemaReal 04.11.2017 20:18 # 0
Наследоваться просто чтобы переюзать код это не правильно
inho 04.11.2017 20:26 # 0
bormand 05.11.2017 10:37 # +1
Вот так в жабе и унаследовали Properties от HashTable....
Because Properties inherits from Hashtable, the put and putAll methods can be applied to a Properties object. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are not Strings. The setProperty method should be used instead.
1024-- 05.11.2017 14:51 # 0
Но тут с LSP проблемы какие-то. Это как целое число от действительного наследовать. Вот если и правда перламутровые пуговицы были бы только добавкой к уже существующему...
А, или дело тут ещё и в том, что если мы публично наследуемся, то в последующих версиях они могут сами сделать с перламутровыми пуговицами, и тогда все, кто использовал сам класс, не пострадают (обратная совместимость), а все, кто унаследовался - окажутся в зоне риска (конфликты имён, конфликты реализаций).
wvxvw 05.11.2017 15:06 # +4
Для тех, кому важна хронологическая точность: The Smalltalk Report, October 1994, Volume 4, Number 2. Страницы с 4 по 10.
3.14159265 08.11.2017 00:40 # +2
Вот год очень кстати. И уже тогда автор начал просекать: "что-то здесь не то".
>приверженость идеологии ООП, рекламные объявления, где объекты продают и еще всякие странные вещи с ними делают, и совсем недорого.
Помнится один умный человек говаривал что "это ваше ООП напоминает гербалайф".
SemaReal 08.11.2017 00:46 # +2
Desktop 18.01.2020 18:14 # −1
- я, конечно, боюсь быть осмеянным вореционными профессорами, но всё же поинтересуюсь, как в процедурном подходе мне что-нибудь заmockать, чтобы потом заюзать в юнит-тестах тестовую реализацию вместо обычной?
gost 18.01.2020 18:42 # 0
Смекаешь?..
AnalBoy 18.01.2020 18:43 # +1
HoBorogHuu_nemyx 18.01.2020 18:44 # +1
Desktop 18.01.2020 18:47 # 0
gost 18.01.2020 19:56 # +1
Приведи реальный пример кода, который нельзя «замокать» при помощи «Ctrl+Ins, Shift+Ins».
gostinho 18.01.2020 19:57 # 0
Desktop 18.01.2020 20:15 # 0
gost 19.01.2020 01:58 # +1
Да как и везде тестируют: берут какую-нибудь «Цмоку»* и вперёд, на баррикады. Именно поэтому я за «цмок».
*https://cmocka.org/
HoBorogHuu_nemyx 19.01.2020 02:39 # +1
Цари вставляют printf прямо в рабочий код, а перед выпуском программы его комментируют.
Koko 19.01.2020 02:52 # +2
3.14159265 20.01.2020 15:52 # +1
Я уже объяснял вам, клоунам, про то что сишка первична.
А потом прибегают ублюдки, берут printf и прикручивают поверх него примитивный if.
Или хуже того — пилят свои говнологгеры.
Это работает через жопу.
Очевидно, что в ваших мусорных недоязычках с помойки нет препроцессора.
По причине, что авторы этого мусора — биомусор.
Цари же добавляют сишнокрестовому компилятору флаг -DNDEBUG и сливают анскильных лалок в хламину.
gost 20.01.2020 16:02 # +1
3.14159265 20.01.2020 16:08 # +1
Хотя тут даже ненужны прошлые фиксации — всё видно сейчас.
Во-первых мы здесь не видим ответа, какой-то контр-аргументации, либо вопроса.
Ничего нет — есть попытка включать идиота, будто бы этот клоун не знает того о чём я говорю, хотя понятие «препроцессора в Си» вполне себе очевидно.
Второе и самое важное - тут сразу можно заметить, как это отребье начинает меня обзывать и в чём-то обвинять.
Но опять, как видно бездарность ничего конкретного не сказал и ничего не обосновала.
Это явный офтоп, это явные оскорбления, это явный тупняк, это явная мразь. Фиксируем.
gost 20.01.2020 16:11 # +1
gostinho 20.01.2020 16:15 # 0
AnalBoy 18.01.2020 18:41 # 0