Здравствуйте, fin_81, Вы писали:
_>Здравствуйте, samius, Вы писали:
_>Что-то скучно стало. Есть дела повеселее. Признаю свое поражение. За сим откланяюсь.
Редкий поступок. Уважаю! Серьезно.
Здравствуйте, Философ, Вы писали:
Ф>Здравствуйте, samius, Вы писали:
S>>"Похоже" — это как-то не аргумент против определения в википедии.
Ф>Любое слово является аргументом против любого слова/группы слов/статьи в википедии.
Я хотел сказать что "похоже" — не убедительный для меня аргумент против определения в википедии. Если для вас он убедительный, то рад за вас.
Ф>Википедия — хреновый источник
Приведите нехреновый. Лучше с вашими критериями оценки качества источника, что бы можно было построить предметный разговор.
Все строиться вокруг "переменной". Более теоретически чистые функциональные языки идут лесом. Это камень в огород такого определения полиморфизма.
Забавляет определение
Полиморфизм — это одинаковое или разное поведение для разных типов. Напрашивается упрощение: полиморфизм — это какое-то поведение для данных разных типов. Под такое упрощенное определение любое поведение. Хороший термин, всеобъемлющий.
Начинают притягивать это "модное определение" ко всему подряд и выясняется что почти любая конструкция языка это полиморфизм. Поэтому приходится уточнять что за полиморфизм. При этом выясняется что у этого уточнения есть свое определение, более точное. Наследование — это механизм полиморфизма, перегрузка функций — это тоже механизм полиморфизма, обобщеннное программирование(метапрограммирование) — это механизм полиморфизма, можете продолжить список.
Здравствуйте, samius, Вы писали: S>При единственной задаче софта "работать" — самое тупое решение, при котором софт будет работать, является оптимальным.
Ты знаешь... я вот только что переписал с нуля софт, который народ писал четыре года. За две недели. Так вот, самое тупое решение которое работает, является оптимальным.
S>А когда у вашего софта наметятся другие задачи, тогда и обсудим, как на них скажутся глобальные переменные и MainForm.Instance.CurConfig.бла-бла.
А вот задачи софта к культуре написания кода совершенно перпендикулярны. Вот ты, лично, при хорошей культуре разработки, любишь придумать на ровном месте огромную кучу лишних задач "на перспективу", хотя для конкретной задачи этого совершенно не нужно. В итоге получается такой клубок паттернов, в котором без поллитра фиг разберешься.
Всё, что нас не убивает, ещё горько об этом пожалеет.
Здравствуйте, Ромашка, Вы писали:
Р>Здравствуйте, samius, Вы писали: S>>При единственной задаче софта "работать" — самое тупое решение, при котором софт будет работать, является оптимальным.
Р>Ты знаешь... я вот только что переписал с нуля софт, который народ писал четыре года. За две недели. Так вот, самое тупое решение которое работает, является оптимальным.
Недостаточно данных, что бы я мог это как-то комментировать.
S>>А когда у вашего софта наметятся другие задачи, тогда и обсудим, как на них скажутся глобальные переменные и MainForm.Instance.CurConfig.бла-бла.
Р>А вот задачи софта к культуре написания кода совершенно перпендикулярны. Вот ты, лично, при хорошей культуре разработки, любишь придумать на ровном месте огромную кучу лишних задач "на перспективу", хотя для конкретной задачи этого совершенно не нужно. В итоге получается такой клубок паттернов, в котором без поллитра фиг разберешься.
Я так не считаю, мой начальник (программист) так не считает. Во всяком случае уровень сложности и гибкости решений мы с ним обговариваем и он претензий ко мне в этом отношении не высказывал.
Откуда дровишки?
Я предполагаю, но с тем человеком мы не сошлись во мнениях лишь в одном вопросе на моей памяти. И этот вопрос не касался программирования.
Здравствуйте, Voblin, Вы писали:
V>Полиморфизьм основывается на наследовании.
Строго говоря, это же не правда...
Вот, например в старом добром С были примеры вполне так себе полиморфных #define MAX( X, Y ) ( (X) > (Y) ? (X) : (Y) ) ну и вполне так себе полиморфная qsort...
Но это тут не главное. Главное тут, IMHO, другое.
V> А что от чего должно быть унаследовано определяется в самом начале, и потом перетряска дерева наследования — жуткий гемор. Получается так, что существенное решение принимается в самом начале, когда нет всей полноты информации.
Строго говоря, это вообще свойство проектирование такое. Ошибки в архитектуре самые трудноисправимые...
Собственно конкретно ООП там или инкапсуляция с полиморфизмом тут не при чём.
Это просто такое вот войство проетирования сложных систем. Тут это лечитя не ООП там или ещё каким ссеребрянным ятаганом, а путём инженерной школы, опыта там, головы, приложенной в нужное место нужным образом и всего такого...
А споры о том, что такое тру ООП, а что нет к этой РЕАЬНОЙ проблеме никакого отношения не имеют...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, McSeem2, Вы писали:
MS>Все это такое фуфло, я вас скажу эти ваши философии.
Всё в порядке, дружище, дыши глубже.
MS>Так же как и много других умных слов про программирование. На практике же, надо просто решать конкретную прикладную задачу, вот и все. И в результате оказывается, что умные программеры во всем коде на C# (!) во всю используют глобальные переменные! Как на старом добром Фортране — везде фигурирует MainForm.Instance.CurCofig.бла-бла. Ну и че? Это плохо? Нет — это нормально. Потому что софта работает и выполняет свою задачу.
Угу, это нормально.
MS>Ну это наверное мое личное мировосприятие — программирование является лишь вспомогательным инструментом для решения более серьезных задач, инженерного и научного типа.
Да, так и есть. Программы ценны только в контексте задач, ради которых они пишутся.
MS>И пофигу на весь этот ваш умный computer science, тем более, что иногда приходится объяснять, что поделить на 10 это не то же, что умножить на 0.1 — вот в чем заключается computer science, а не в том, что бы наследовать хрень от белиберды или наоборот.
Вся проблема в том, что "умные слова про программирование" — это побочная наукообразная ветка от дерева Computer Science. Так что, ты не смешивай одно с другим. Для примера погугли по словами Liskov Substitution Principle: как он звучит в оригинале и во что превращён "умными словами".
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, McSeem2, Вы писали:
MS>везде фигурирует MainForm.Instance.CurCofig.бла-бла. Ну и че? Это плохо? Нет — это нормально.
Ну, если человек в инвалидном кресле с воткнутой капельницей в вену нормально, то да, ничего такого плохого.
Как по мне — это криво, потому что в конкретном месте кода моего класса мне нужен CurCofig. И мне фиолетово откуда от возьмется настолько, что я и знать этого не желаю.
Откуда он берется, вчера, сегодня, завтра, как его получить — это НЕ забота моего кода.
Если он конечно — здоров. Если болен — то конечно, нормально усадить в кресло с колесиками, воткнуть капельницу в руку, и на рот маску к кислородному баллону.
Мало того, все эти гирлянды:
get1().get2().get3().get4().get5()....
вызывают подозрение в мышлении постоянно пишущего такое. Конечно, для разового применения — допустимо. Но если в одном методе — дважды, то:
— это признак не понимания разницы между ЧТО и КАК. Или — безвкусица мышления.
достаточно упрятать эту гирлянду в отдельный метод, чтобы разделить это ЧТО мне нужно, от КАК получить это нечто
Особенно умиляет когда есть базовый класс, а во всех наследниках эти гирлянды.
Уж точно — наследники должны вызывать метод базового класса, в котором упрятано это КАК получить.
Здравствуйте, samius, Вы писали: S>Недостаточно данных, что бы я мог это как-то комментировать.
Ты опять усложняешь. Вывод очень простой — 90% (и это очень оптимистичная оценка) написанного программистами кода банально не нужны.
S>Я так не считаю, мой начальник (программист) так не считает. Во всяком случае уровень сложности и гибкости решений мы с ним обговариваем и он претензий ко мне в этом отношении не высказывал. S>Откуда дровишки?
Земля шарик маленький. Еще раз, Samius, я хорошего мнения о тебе и о твоем коде. Речь не о красоте, сложности, гибкости или еще каких-либо метриках кода, речь о том, что этот код просто никому не нужен (кроме программиста и его начальства). Это, вообще говоря, проблема совсем не программистов — нам пофиг, пока деньги капают, мы пишем (чем больше пишем, тем дольше капают деньги).
ТС говорит о том, что если код нужен, всем плевать на то, макароны там или паттерны, а пользователи готовы мириться с умопомрачительным количеством глюков на квадратный килобайт кода. Ты говоришь о том, что нужно писать хороший код. Вы оба правы, вы просто о разном говорите.
Всё, что нас не убивает, ещё горько об этом пожалеет.
Здравствуйте, Ромашка, Вы писали:
Р>Здравствуйте, samius, Вы писали: S>>Недостаточно данных, что бы я мог это как-то комментировать.
Р>Ты опять усложняешь. Вывод очень простой — 90% (и это очень оптимистичная оценка) написанного программистами кода банально не нужны.
На счет 90 не знаю, но в принципе поддержу. Сам 8 лет своей жизни писал практически в стол. В то время как обычно код теряет актуальность не сразу, я писал в стол сразу и бесповоротно. Несколько лет понадобилось что бы это осмыслить и еще пару я пописал в стол просто по инерции.
Р>Земля шарик маленький. Еще раз, Samius, я хорошего мнения о тебе и о твоем коде. Речь не о красоте, сложности, гибкости или еще каких-либо метриках кода, речь о том, что этот код просто никому не нужен (кроме программиста и его начальства). Это, вообще говоря, проблема совсем не программистов — нам пофиг, пока деньги капают, мы пишем (чем больше пишем, тем дольше капают деньги).
Здесь я не соглашусь. Я могу писать лишнее потому как не понял задачу, или после написания изменилось видение пути решения. Но такого не было что бы мне дали деньги (зарплату) и сказали бы пиши и не думай, зачем это надо и кому сделает жизнь лучше. Конечно, если бы мне не платили зарплату, я бы занимался чем-то другим.
Р>ТС говорит о том, что если код нужен, всем плевать на то, макароны там или паттерны, а пользователи готовы мириться с умопомрачительным количеством глюков на квадратный килобайт кода. Ты говоришь о том, что нужно писать хороший код. Вы оба правы, вы просто о разном говорите.
На моей памяти довольно много нужного кода было отвергнуто по причине глюков, либо трудоемкости его развития.
А однажды именно глобальные переменные (и их обилие) привело к нехилому усложнению и удорожанию интеграционного тестирования. Я не хочу сказать что так должно быть с каждым проектом. Просто говно выстреливает. И чем актуальнее код, тем больнее прилетает. Это мой опыт.
Здравствуйте, fin_81, Вы писали:
_>И так возвращаясь к сути. Множество состоящее из наследования — это подмножество полиморфизма?
Наследование, само по себе, не является полиморфизмом. Наследование — это лишь механизм, позволяющий добиться динамического ad-hoc полиморфизма (по типу неявно передаваемого параметра this) в языках программирования, в который наследование имеет "subtyping" семантику (грубо говоря, разрешено приведение к базовому типу). Вполне возможен такой язык (причем, он будет OO языком), в котором есть наследование, но запрещено явное и неявное приведение к базовому классу (чтобы нельзя было нарушить LSP), а ОО-шный полиморфизм делается только на интерфейсах.
Здравствуйте, jazzer, Вы писали: J>Точно. Мало того, еще и одну из лучших векторных библиотек AGG написал. Гнать из профессии мокрыми тряпками.
Ну зачем же так. Я в позитивном ключе: у нас в стране философов меньше чем фотографов, а тут такой демагогический талант пропадает.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, fin_81, Вы писали:
_>>И так возвращаясь к сути. Множество состоящее из наследования — это подмножество полиморфизма?
A>Наследование, само по себе, не является полиморфизмом. Наследование — это лишь механизм, позволяющий добиться динамического ad-hoc полиморфизма (по типу неявно передаваемого параметра this) в языках программирования, в который наследование имеет "subtyping" семантику (грубо говоря, разрешено приведение к базовому типу). Вполне возможен такой язык (причем, он будет OO языком), в котором есть наследование, но запрещено явное и неявное приведение к базовому классу (чтобы нельзя было нарушить LSP), а ОО-шный полиморфизм делается только на интерфейсах.
Более того, мы знаем такой язык. В нём достаточно написать class B: private A, как мы тут же потеряем способность передавать ссылки на B в произвольный код, ожидающий A. Т.е. наследование — есть, а полиморфизма — нету.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Voblin, Вы писали:
V>Для того, чтобы летать, нужны крылья. Это тоже полуправда. Потому что летать можно по-разному, с том числе и из окна вниз головой. Но когда есть крылья, летать получается проще и естественнее
Пингвина видел? А эму?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Мои извинения за задержку с ответом, много чет навалилось. Со всем поскипаным согласен.
S>А однажды именно глобальные переменные (и их обилие) привело к нехилому усложнению и удорожанию интеграционного тестирования. Я не хочу сказать что так должно быть с каждым проектом. Просто говно выстреливает. И чем актуальнее код, тем больнее прилетает. Это мой опыт.
Оно всегда прилетит, чудес не бывает. Я не знаю, как это точно называется, я называю это слабо/сильно интегрированными системами. Слабо интегрированные системы это и есть лапша. Замечательный пример — 1Ц. Классический говонокод — вся логика на формах, глобальные переменные и прочие радости. Такой подход дает постоянную (по мере усложнения проекта) цену на добавление нового функционала и быстро растущую стоимость изменения системы. Понятно почему, попытка что-либо изменить приводит к необходимости переписать весь проект. В противоположность этому есть сильно интегрированные системы. Там стоимость добавления нового функционала растет по мере увеличения сложности, а стоимость изменения системы остается постоянной.
Так вот, стоимость написания нового кода в любом проекте рано или поздно превысит комфортный предел. Либо на добавление, либо на изменения. Мы можем только несколько отодвинуть этот момент. Причем я не уверен, что надолго.
Всё, что нас не убивает, ещё горько об этом пожалеет.
Здравствуйте, Ромашка, Вы писали:
Р>Здравствуйте, samius, Вы писали:
Р>Мои извинения за задержку с ответом, много чет навалилось. Со всем поскипаным согласен.
Ничего страшного, куда спешить?
Р>Оно всегда прилетит, чудес не бывает.
Бывают чудеса в виде проектов в стиле "написал и забыл" при условии что длительность написания мала. Мы их не рассматриваем в контексте стоимости внесения изменений. Это не возражение, а так, уточнение.
Р>Я не знаю, как это точно называется, я называю это слабо/сильно интегрированными системами. Слабо интегрированные системы это и есть лапша. Замечательный пример — 1Ц. Классический говонокод — вся логика на формах, глобальные переменные и прочие радости. Такой подход дает постоянную (по мере усложнения проекта) цену на добавление нового функционала и быстро растущую стоимость изменения системы. Понятно почему, попытка что-либо изменить приводит к необходимости переписать весь проект. В противоположность этому есть сильно интегрированные системы. Там стоимость добавления нового функционала растет по мере увеличения сложности, а стоимость изменения системы остается постоянной.
Я понял, о чем речь. Предлагаю ввести понятие "направления изменений" и характеризовать системы адекватностью предполагаемым направлениям изменений.
Таким образом, названные тобой слабо интегрированные системы (логика на формах, глобальные переменные и прочие гадости), будут безобразно дешевы в плане добавления кнопки и изменения той самой логики обоработки кнопки, но затратны в плане превращения в веб-серис. Пока не грозит превращение в веб-сервис — кашляли мы на эти затраты.
Допустим, пописали мы систему год и увидели что риск внесения ошибок при изменении системы вырос до нежелательных величин. Выходы следующие: команда тестеров — дорого (это предположение, может и совсем не дорого), автоматизированное тестирование — дешево, но надо все переписать и потратить время на реализацию нефункциональных для заказчика вещей.
Ладно, переписали. Теперь все грамотно, логика в отдельном проекте, глобальных переменных нет (мешали тестировать... не знаю, кому как, а мне мешают), прикрутили MV"?", DI-контейнеры, и получили ад при добавлении кнопки на форму. Зато система на счет раз превращается в веб-серивс...
Р>Так вот, стоимость написания нового кода в любом проекте рано или поздно превысит комфортный предел. Либо на добавление, либо на изменения. Мы можем только несколько отодвинуть этот момент. Причем я не уверен, что надолго.
Рано или поздно потухнет солнце, но нас это не сильно беспокоит
По поводу комфортного предела — не соглашусь. Нет такого предела в его абсолютном значении, как и нет предела сложности системы. Есть вот такие вопросы и ответы на них:
* Что мы можем предпринять для того что бы вот такого рода изменения сделать комфортными на сколько это возможно?
* Какова будет цена этого комфорта?
* Что мешало (или не давало повода) подумать об этом на стадии комфортного изменения/переписывания всей системы?
Потом начинается новый проект, смотрим на вводную и думаем, где нужно подстелить по минимуму, что бы посередине проекта не пришлось бы его переписывать. И тогда находится коллега, который говорит:
— Чувак! Ты напереоверинженерил!
Да, возможно. И если бы я 4 года назад знал все текущие требования и удачные решения, возможно я бы и написал систему за пару месяцев в окончательном виде без комфорта при внесении внезапных изменений.
Но практика опять же показывает, что требования меняются даже у задач, которые нужно просто переписать, и казалось бы, все про них уже известно.
Здравствуйте, jazzer, Вы писали:
J>Это как в Java, когда раз ООП, то не должно быть свободных функций, и поэтому надо рожать бессмысленные классы для свободных по сути функций типа синуса и main. Зато чистый ООП, только классы.
Здравствуйте, Sinclair, Вы писали:
_>>>И так возвращаясь к сути. Множество состоящее из наследования — это подмножество полиморфизма?
A>>Наследование, само по себе, не является полиморфизмом. Наследование — это лишь механизм, позволяющий добиться динамического ad-hoc полиморфизма (по типу неявно передаваемого параметра this) в языках программирования, в который наследование имеет "subtyping" семантику (грубо говоря, разрешено приведение к базовому типу). Вполне возможен такой язык (причем, он будет OO языком), в котором есть наследование, но запрещено явное и неявное приведение к базовому классу (чтобы нельзя было нарушить LSP), а ОО-шный полиморфизм делается только на интерфейсах. S>Более того, мы знаем такой язык. В нём достаточно написать class B: private A, как мы тут же потеряем способность передавать ссылки на B в произвольный код, ожидающий A. Т.е. наследование — есть, а полиморфизма — нету.
Всех тонкостей не помню, но в дружественной функции вроде можно кастовать к приватному базовому типу.
Что такое "наследование"?
Достаточно написать "class B: private A" и мы получаем агрегацию/композицию, а не наследование.
Для полноты картины: что такое инкапсуляция и полиморфизм?
Здравствуйте, fin_81, Вы писали:
_>Всех тонкостей не помню, но в дружественной функции вроде можно кастовать к приватному базовому типу.
Можем, да. Вот такой вот ограниченный получается полиморфизм.
_>Что такое "наследование"?
Наследование — это отношение is-a. В конкретных языках оно может быть реализовано несколько по-разному, но в целом обычно мы наблюдаем следующие черты:
1. Subtyping между родителем и наследником, следствием которого является совместимость по присваиванию ссылок и указателей.
2. Наследование состояния: каждый экземпляр потомка содержит в себе полное состояние предка (используется для обеспечения п.1)
3. Наследование поведения: все экземплярные методы предка работают и на потомке. Поведение статических методов и конструкторов зависит от вкусов дизайнеров языка; как правило, они не наследуются.
4. Полиморфизм экземплярных методов: потомок может переопределять некоторые методы предка, меняя их поведение.
_>Достаточно написать "class B: private A" и мы получаем агрегацию/композицию, а не наследование.
Вы бы всё же разобрались в основах. Всего четыре термина в ветке, а вы уже сорок постингов отказываетесь принять их общепринятые определения.
В частности, приватное наследование — это всё же наследование, а вовсе не агрегация.
_>Для полноты картины: что такое инкапсуляция и полиморфизм?
Инкапсуляция — возможность предоставлять различные контракты различному коду. В самом примитивном виде мы отличаем "внутренний" код от "внешнего" (секции interface и implementation в классическом Паскале или ); в более интересном виде мы можем отличать "код потомков данного класса в любой сборке", "код посторонних классов в данной сборке", и т.п.
Про полиморфизм всё уже сказано здесь: http://rsdn.ru/forum/philosophy/2853873