Re[27]: Override для произвольного метода.
От: 4058  
Дата: 19.12.08 13:14
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, 4058, Вы писали:


PD>Ну значит все, кто этот подход используют, начинающие. Вот, например, некий начинающий программист из Microsoft писал Wordpad


PD>class CColorMenu : public CMenu

PD>class CDocOptPage : public CCSPropertyPage
PD>class CTrackFile : public CFile
PD>class COptionSheet : public CCSPropertySheet
PD>class CComboRulerItem : public CRulerItem
PD>class CRulerBar : public CControlBar
PD>class CEmbeddedItem : public COleServerItem

1. Где детали? Ты уверен, что здесь используется наследование в чистом виде (без полиморфизма)?
2. Еще раз. MFC тонкая прослойка над WINAPI, поэтому делегирование сообщений осуществляется в тупую через наследование (но никто сейчас не станет спорить, что это правильный и изящный способ).

PD>и т.д. Там их много. Он же не знал, как правильно, он же начинающий , он же не умел отличить хорошее от плохого.


Вообщем недалеко от истины.
Правда у нас очень разные представления на счет "начинающих".

PD>А MS , вместо того, чтобы стыдиться такого продукта от начинающих, взяла да и выставила его на всеобщее обозрение в качестве примеров. Для других начинающих, надо полагать


Ну и кому еще нужны такие примеры, кроме как начинающих?

PD>Я так подозреваю, что если бы исходники других приложений были доступны, то выяснилось бы, что многие приложения от MS писали начинающие. Включая .Net


Исходники многих компонентов .NET доступны (в том числе VM), поэтому положительная динамика, с точки зрения качества кода имеется.

4>>1. Есть проекты, которые никто не станет переписывать с нуля более "кошерными" средствами, но которые тем не менее требуют доработок.


PD>А что же они 10 с лишним лет ее не требовали, и MFC не развивалась, а тут вдруг потребовали ? Что изменилось-то ?


M$ надеялась, что сможет пересадить львиную долю formo-кодеров на .NET, не получилось...

4>>2. Осталось большое сообщество консервативно настроенных пользователей, которым просто в лом посмотреть по сторонам. Их тоже приходится поддерживать.


PD>. Нет, ребята, с вашей логикой не соскучишься . Зачем их поддерживать-то ? Наоборот, их надо ограничивать, чтобы они на новые прогрессивные технологии переходили.


Пытались, но до добра это дело не довело (см. про formo-кодеров).

PD>А вообще забавно смотреть, как вы из кожи лезете вон, пытаясь во что бы то ни стало доказать, что то, чем вы занимаетесь, и есть единственно правильное, а все остальное устарело, консервативно, смотреть по сторонам не хотят и т.д. Забавно.


Павел, с MFC основательно имел дело эдак 10-ть лет назад, с того времени много воды утекло — STL/ATL/WTL/Java/.NET + *nix. Поэтому я (да и многие другие кто пытается тебе тут объяснить, что 2*2=4) не упустили возможность не однократно пересмотреть свои убеждения.
Re[28]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 23.12.08 07:30
Оценка:
Здравствуйте, 4058, Вы писали:

4>1. Где детали? Ты уверен, что здесь используется наследование в чистом виде (без полиморфизма)?


Нет, конечно. Детали — в исходниках, они доступны в Platform SDK. Копаться не буду, вполне возможно, что там полиморфизм есть.

4>2. Еще раз. MFC тонкая прослойка над WINAPI, поэтому делегирование сообщений осуществляется в тупую через наследование (но никто сейчас не станет спорить, что это правильный и изящный способ).


Сообщения в MFC как раз сделаны не совсем через наследование, точнее, не через виртуальность. Там есть свои обработчики сообщений, некая собственная пародия на виртуальность. Идея сводится к тому, что каждый класс иммет массив указателей на свои обработчики сообщений и поиск идет в этом массиве, а коли не найдется — у родителя. Сделано это с целью уменьшить размеры виртуальных таблиц — в vtable если указатель на метод однажды попадет, то быть ему там у всех наследников, даже если они этот метод не перекрывают, а в массиве этом есть только то, что этому классу нужно. Не очень элегантное решение...

PD>>и т.д. Там их много. Он же не знал, как правильно, он же начинающий , он же не умел отличить хорошее от плохого.


4>Вообщем недалеко от истины.

4>Правда у нас очень разные представления на счет "начинающих".

Видишь ли, независимо от того, как представлять себе начинающих, это — пример от MS. То есть MS считает (или считала как минимум), что такой код или такой подход можно выставить на всеобщее обозрение в качестве того, что она считает корректным и допустимым. Никакая уважающая себя фирма, никакой уважающий себя автор учебника не станет приводить примеры, которые противоречат существующим правилам игры. Кто будет это читать — начинающие или гуру — не столь важно, важно лишь одно — это фирма выставила как свою визитную карточку , она говорит — мы так делаем, по-нашему — это хорошо.

Тем более что речь все же идет не о специально созданном примере, а об исходниках пусть не самого мощного , но все же штатного текстового редактора, который по идее должен использоваться для реальной работы с .doc файлами теми, кто не купил Office (OO тогда не было

PD>>А MS , вместо того, чтобы стыдиться такого продукта от начинающих, взяла да и выставила его на всеобщее обозрение в качестве примеров. Для других начинающих, надо полагать


4>Ну и кому еще нужны такие примеры, кроме как начинающих?


Даже если пример содержит только printf("Hello, World"), его писать и выставлять надо сделанным как следует.

PD>>Я так подозреваю, что если бы исходники других приложений были доступны, то выяснилось бы, что многие приложения от MS писали начинающие. Включая .Net


4>Исходники многих компонентов .NET доступны (в том числе VM), поэтому положительная динамика, с точки зрения качества кода имеется.


Ох, сомневаюсь я в этой динамике. С точки зрения возможностей и набора средств — безусловно, .Net дает 100 очков вперед MFC. Библиотека богатейшая. Но вот с точки зрения реализации... Я уже как-то приводил пример, когда в listview для того, чтобы провести сортировку, они создают новый контрол (новое окно) и переливают в него все данные. За такие вещи раньше били шомполами, да и сейчас, если мне студент такое покажет, я его без лишних слов отправлю переделывать. MFC в этом смысле сделана на порядок лучше — я в ее исходниках не раз копался, могу сказать — некоторые фрагменты написаны так, что хоть вытаскивай их оттуда и используй в качестве демонстрационного пособия по Win32 — лучше все равно не напишешь.

4>>>1. Есть проекты, которые никто не станет переписывать с нуля более "кошерными" средствами, но которые тем не менее требуют доработок.


PD>>А что же они 10 с лишним лет ее не требовали, и MFC не развивалась, а тут вдруг потребовали ? Что изменилось-то ?


4>M$ надеялась, что сможет пересадить львиную долю formo-кодеров на .NET, не получилось...


Что же ты многоточие поставил ? Надо закончить фразу. Не получилось — а почему ? И библиотека хорошая, и язык C# (взятый сам по себе) — лучше C++, логичнее, а вот не получилось. Почему ? Должны же быть причины ?

4>>>2. Осталось большое сообщество консервативно настроенных пользователей, которым просто в лом посмотреть по сторонам. Их тоже приходится поддерживать.


PD>>. Нет, ребята, с вашей логикой не соскучишься . Зачем их поддерживать-то ? Наоборот, их надо ограничивать, чтобы они на новые прогрессивные технологии переходили.


4>Пытались, но до добра это дело не довело (см. про formo-кодеров).


А почему в случае Win16 -> Win32 все прошло успешно ?

PD>>А вообще забавно смотреть, как вы из кожи лезете вон, пытаясь во что бы то ни стало доказать, что то, чем вы занимаетесь, и есть единственно правильное, а все остальное устарело, консервативно, смотреть по сторонам не хотят и т.д. Забавно.


4>Павел, с MFC основательно имел дело эдак 10-ть лет назад, с того времени много воды утекло — STL/ATL/WTL/Java/.NET + *nix. Поэтому я (да и многие другие кто пытается тебе тут объяснить, что 2*2=4) не упустили возможность не однократно пересмотреть свои убеждения.


Что же, я с уважением готов относиться практически к любому чужому убеждению. Но все же останусь при своем
With best regards
Pavel Dvorkin
Re[28]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 23.12.08 08:26
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>Ну полезны они или нет — об этом можно просто по ссылкам на них судить.
S>Это и есть "голосование".

Это есть некая подмена понятий, довольно-таки тонкая. Если голосованияе проводится явно (то есть задается вопрос — счтаете ли вы codeproject серьезным ресурсом) — это и есть глосование. Но такого голосования никто не проводил. То, что я привел — есть результат подсчета популярности ресурса (аналогично рейтингам Гэллапа и т.д.) по независимым данным. Те, кто на этот ресурс ссылались — вовсе не думали о том, что кто-то будет этот факт использовать в каких-то целях. А поэтому такая оценка (рейтинга) дает основание делать выводы о популярности ресурса.

PD>>Индус он или китаец — меня очень мало интересует. Качество этого класса меня будет интересовать только если я решусь его применить (это, впрочем, верно для любых классов). Я же аргументирую тем, что такое делается, и это норма.

S>Это и есть "голосование". Можно, я аргументирую правильность ежедневного приема героина внутривенно тем, что такое делается? Уверяю тебя, эта практика значительно более распространена, чем использование класса CStringEx.
S>Понятно, почему голосования не помогают?

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


PD>>Передергиваем опять. Ссылку в студию, где я сказал, что любой код оттуда жемчужина ?

S>Ты считаешь сам факт наличия этого класса там свидетельством того, что это "норма".

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

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

S>Ты пытался к нему апеллировать. Типа "раз вы не можете доказать, что этот сайт — отстой, значит любой код оттуда — жемчужина".


Передергиваем опять. Ссылку в студию, где я сказал, что любой код оттуда жемчужина ?

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Я здесь заявляю, что утверждение, будто любой код оттуда — жемчужина , мне приписывать не надо, и требую ссылку, где я такое якобы заявлял. Ссылку ты не даешь (ее в природе не существует), а вместо этого заявляешь, что якобы я считаю наличие одного какого-то класса нормой. Хот я ясно, кажется, сказал, что не идет речь о любом коде. Как это называть ?

PD>>Опять демагогия. Покажи мне софт (да еще с исходниками, надо полагать, для обсуждения устройства-то) и тогда обсудим, мол. Софта, написанного с помощью MFC, сколько угодно, а какие там расширения ее используются, я, естественно, не знаю, так как исходников у меня нет.

S>Ну, а если ты не знаешь, то зачем привлекаешь частоту использования в качестве аргумента?

Как практику — критерий истины

S>Или ты частоту самого MFC записываешь в аргументы в пользу тезиса "наследоваться от строки с целью добавления туда функций, которые с тем же успехом могли бы быть внешними — это лучше, чем делать их внешними"? Это, пардон, передергивание.


Опять! Говоря о частоте использования примеров с codeproject, мы говорили уже отнюдь не от CStringEx, а о ресурсе codeproject как таковом. И подсчеты мои именно к нему относились, а не к CStringEx ( не помню, чтобы я по этому классу подсчет ссылок приводил).


PD>>а ты что будешь искать ? У меня есть база, от которой я могу начать поиск, а у тебя ?

S>Павел, это несеръезно. Такого поиска в природе не бывает. Реальный разработчик будет искать не класс, а функциональность. Если нужны палиндромы — будут искать palindrome, а не всех мыслимых наследников от строки.

Нет, это очень даже серьезно. Попробуй поискать на google "palindrome" и у тебя сразу настроение испортится.

PD>>Это почему же ? Я напишу свой хелпер, ты свой (мы же не договаривались), кто-то еще — свой. С чего это им ортогональными бцть ?

S>Ты понимаешь смысл термина "ортогональны"? Без договоренностей хелперы всегда будут ортогональными.

Похоже, мы под словами "ортогональность" понимаем разное. Для меня ортогональный АПИ — это АПИ, в котором любое действие можно сделать одним и только одним способом. В этом смысле такие хелперы не будут ортогональными, так как без договоренностей неизбежно эти хелперы будут пересекаться (Dvorkin.IsPalindom и Sinclair.IsStringPalindrom, даже имена могут не совпасть. Только если одна команда будет делать эти хелперы — можно на что-то надеяться.

PD>>Это все было бы ничего, если бы мы были членами одной команды и разделили работу. Тогда да, согласен. Но мы не члены одной команды, а поэтому перекрытия возможны и почти обязательно будут. В итоге, если их не мерджить, то просто получим набор перекрывающихся по функциям (полностью или частично) методов, в которых нет ни логики, ни какой-то организации.

S>С чего бы это? Это жертвы MFC пихают в своего наследника от CString все расширения, без всякой логики или организации. Просто потому, что строка у них вынуждена быть ровно одного класса, а значит все методы надо запихать в нее. И по работе с ресурсами, и по форматированию.

А вы собираетесь все расширения в разные хелпры засунуть, что никак не лучше, потому что вместо иерархии, в которой можно разобраться, и в которой вполне достаточно иметь хелп по последнему (лучшему) наследнику, вы получите фактически возврат к языку С, так как каждый из ваших хелперов, если они static, по существу представляет собой набор отдельных функций, объединенных именем класса. Уберите класс — и чистый C перед вами, без всякой организации. А и не убирая — имеем набор отдельных кусков разного происхождения и никак не связанных логикой. Пользователю — сиди и ищи, в каком из этих кусков нужное ему есть и если есть в нескольких кусках — где лучше сделано. Голова пухнет


S>А поскольку мы с Иваном думаем по-другому, каждый будет делать хелпер исходя из Single Responsibility Principle.

S>И за палиндромы будет отвечать хелпер палиндромов, за поиск регулярных выражений — регулярные выражения, за конверсию в определенную кодировку — Encoding.

Эхе-хе. Мы же не договариваемся, мы же члены разных команд. Я же о твоих действиях ничего не знаю. Вот и сделаю я PalindromHelper и ConversionHelper и т.д. А ты, ничего об мне не зная, свои такие (да нет, не такие, а несколько иные) соорудишь. Иван о нас тоже не знает, он свои сделает. В каждом из них чего-то не хватать будет, а что-то не лучшим образом сделано будет. Было бы наследование — не стал бы я свой хелпер делать, зная о том, что твой сущетсвует, а попробовал бы его улучшить. А ты потом мой. А Иван твой. И в итоге имели бы BestPalindromHelper и BestConversionHelper. А так вместо этого иметь будем 3 набора хелперов от меня , тебя и Ивана, и каждый из нас будет доказывать преимущества своего хелпера. А Вася Пупкин, ошалев от нашей дискуссии и поняв, что ему придется брать 2 метода из моего, 3 — из твоего и один — из Ивана, плюнет на нас троих и начнет свой Pupkin.PalindromHelper сочинять

S>По факту оказывается, что это гораздо более логичный и организованный код, чем беспорядочное наследование и всовывание методов по принципу "свалим всё в один класс, чтобы было проще найти".


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


PD>>Каждый делал как мог и как хотел, а тот, кто эти 3 чуда захочет использовать, будет сидеть и плеваться. потому что он будет использовать один метод из Dvorkin, 2 из Sinclair и т.д, а знать должен о всех.

S>Он и так должен знать обо всех.

Зачем. См выше — он должен знать только о BestPalindromHelper. Ты когда пишешь код для Listbox и вызываешь его методы — часто вспоминаешь, что он еще и Control, и Component, и MarshalByRefObject ? Знать об этом ты должен, да, но хелпа по ListBox тебе вполне хватит, как правило.


S>Ты всё еще мне не ответил на вопрос — что же делать в такой же ситуации в твоем подходе. Вот, допустим, мы все послушались тебя, и вместо внешних хелперов каждый написал свой наследник от CString. Что делает прикладной программист, который хочет воспользоваться всеми тремя группами функций?


Э нет, не все так просто. См выше о PalindromHelper и BestPalindromHelper. Впрочем, хелперы уберем, вернемся к классу. В итоге получится класс CSuperString, в котором сделано именно лучшим образом. И вскоре всем становится известно, что лучшего средства для работы со строками, чем этот CSuperString, и не существует. Ссылок на него море , все его любят и за него голосуют , все им довольны и используют.

А некто X уже придумал как его расширить и улучшить. Уже зреет CCoolString
With best regards
Pavel Dvorkin
Re[29]: Override для произвольного метода.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.12.08 09:03
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>>Это почему же ? Я напишу свой хелпер, ты свой (мы же не договаривались), кто-то еще — свой. С чего это им ортогональными бцть ?

S>>Ты понимаешь смысл термина "ортогональны"? Без договоренностей хелперы всегда будут ортогональными.

PD>Похоже, мы под словами "ортогональность" понимаем разное. Для меня ортогональный АПИ — это АПИ, в котором любое действие можно сделать одним и только одним способом. В этом смысле такие хелперы не будут ортогональными, так как без договоренностей неизбежно эти хелперы будут пересекаться (Dvorkin.IsPalindom и Sinclair.IsStringPalindrom, даже имена могут не совпасть. Только если одна команда будет делать эти хелперы — можно на что-то надеяться.

Обычно под ортогональностью АПИ понимается возможность сделать что-то независимо от других частей АПИ.
Наследуясь от String с целью добавления метода IsPalindrome, а потом попытка использовать его вместо обычных строк — есть нарушение ортогональности. Потому что TextBoxу должно быть пофигу есть в классе метод IsPalindrome или нет. А вам придется сабклассить TextBox (и другие классы), которые рабоать будут со строками.

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


PD>А вы собираетесь все расширения в разные хелпры засунуть, что никак не лучше, потому что вместо иерархии, в которой можно разобраться, и в которой вполне достаточно иметь хелп по последнему (лучшему) наследнику, вы получите фактически возврат к языку С, так как каждый из ваших хелперов, если они static, по существу представляет собой набор отдельных функций, объединенных именем класса. Уберите класс — и чистый C перед вами, без всякой организации. А и не убирая — имеем набор отдельных кусков разного происхождения и никак не связанных логикой. Пользователю — сиди и ищи, в каком из этих кусков нужное ему есть и если есть в нескольких кусках — где лучше сделано. Голова пухнет

Вот stl так сделан. Ниче, людям нравится.
Поэтому в C# придумали Extensionы.
В F# (наверное как и в OCaml) следуют соглашению, если тип зовется vector, то хелперы к нему сгруппированы в модуле Vector.

Вообще вопрос группирования код не сильно связан с ООП, не надо его сюда приплетать.
Re[29]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 23.12.08 10:45
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD> А поэтому такая оценка (рейтинга) дает основание делать выводы о популярности ресурса.

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

PD>Как практику — критерий истины

Данная практика подтверждает, что кривой код существует — это истина.

S>>Павел, это несеръезно. Такого поиска в природе не бывает. Реальный разработчик будет искать не класс, а функциональность. Если нужны палиндромы — будут искать palindrome, а не всех мыслимых наследников от строки.

PD>Нет, это очень даже серьезно. Попробуй поискать на google "palindrome" и у тебя сразу настроение испортится.

...
If you reflect a bit and are honest with yourself, you'll admit that you have this alleged inconsistency with all the nontrivial classes you use, because no class has every function desired by every client. Every client adds at least a few convenience functions of their own, and these functions are always non-members. C++ programers are used to this, and they think nothing of it. Some calls use member syntax, and some use non-member syntax. People just look up which syntax is appropriate for the functions they want to call, then they call them. Life goes on. It goes on especially in the STL portion of the Standard C++ library, where some algorithms are member functions (e.g., size), some are non-member functions (e.g., unique), and some are both (e.g., find). Nobody blinks. Not even you.

(c)Scott Meyers

PD>А вы собираетесь все расширения в разные хелпры засунуть, что никак не лучше, потому что вместо иерархии, в которой можно разобраться, и в которой вполне достаточно иметь хелп по последнему (лучшему) наследнику,

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

PD>вы получите фактически возврат к языку С, так как каждый из ваших хелперов, если они static, по существу представляет собой набор отдельных функций, объединенных именем класса.

Хоть горшком назови.. Ты воспринимаешь наследование, как средство организации кода, но оно для этого не предназначено и никогда не было. И использовать его в этом качестве довольно дурацкая затея, которая ведет к описанным выше проблемам и никакой выгоды, даже в организации кода, не дает.
Для того чтобы логически группировать код — есть неймспейсы, вот их и используй.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[29]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.12.08 03:45
Оценка: 3 (1) +1
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это есть некая подмена понятий, довольно-таки тонкая.
Павел, никакой подмены понятий нет. Как только ты начинаешь привлекать к рассмотрению популярность, ты выходишь за рамки технической дискуссии.
Совершенно неважно, явно ли проводится голосование, или по посещаемости, или по подсчету ссылок на ресурс — в любом случае речь идет о популярности. Которая может определяться техническим совершенством, а может — массовым заблуждением. Поэтому предлагаю завязать с популярностью. Иначе окажется, что лучшее применение наследования — это Стас Пьеха.


PD>С помощью софистики можно доказать все, что угодно. Не ты ли в свое время заявил, что правктика — критерий истины ? Я тебе привожу примеры этой самой практики, эти примеры не по моему заказу сделаны, они исходно существуют. Теперь тебя эти примеры (эта практика) не устраивают, они вдруг оказываются голосованием, к которому у тебя отрицательное отношение. Так разберись все же, является практика критерием или нет.

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


PD>Я здесь заявляю, что утверждение, будто любой код оттуда — жемчужина , мне приписывать не надо, и требую ссылку, где я такое якобы заявлял. Ссылку ты не даешь (ее в природе не существует), а вместо этого заявляешь, что якобы я считаю наличие одного какого-то класса нормой. Хот я ясно, кажется, сказал, что не идет речь о любом коде. Как это называть ?

Это называть — типичными для тебя попытками вывернуться наизнанку, лишь бы не признавать своих заблуждений.
Если твои аргументы не относились к классу CStringEx, то давай их просто выбросим как нерелевантные и всё. Поскольку ты избегаешь прямолинейных утверждений, мне приходится догадываться, что именно ты имел в виду. Вот ты привлек (1)популярность (2)всего ресурса к обоснованию правильности одного конкретного класса. Как мне это трактовать? Как демагогию? В одном посте применено сразу три демагогических приема.


PD>Как практику — критерий истины

Ну так ведь практики-то нет!

PD>Похоже, мы под словами "ортогональность" понимаем разное. Для меня ортогональный АПИ — это АПИ, в котором любое действие можно сделать одним и только одним способом. В этом смысле такие хелперы не будут ортогональными, так как без договоренностей неизбежно эти хелперы будут пересекаться (Dvorkin.IsPalindom и Sinclair.IsStringPalindrom, даже имена могут не совпасть. Только если одна команда будет делать эти хелперы — можно на что-то надеяться.

Это понятно. Поясняю еще раз, специально для тех, кто не знает, что такое Single Responsibility Principle:
Два хелпера, написанные для разных целей, никогда не будут пересекаться по функциональности.
Не может быть такого, чтобы в PalindromManager был метод .GetBytesCount, а в Encoding — .IsPalindrome.
Я вижу, что с пониманием этого у тебя проблемы. Ты вот в качестве примеров привел классы с характерными именами — Dvorkin и Sinclair. Это показывает, что ты трактуешь класс как помойку с методами, классифицированную как угодно, кроме функциональности.

Я предлагаю делить хелперы не по имени автора или еще чему-нибудь, а по Responsibility.

Теперь вернемся к твоему примеру. Ситуация, которую ты привел, может иметь место в таком варианте: есть два класса (в разных неймспейсах, естественно), которые называются, к примеру, PalindromManager. Это само по себе редкая штука — в реальном мире не существует даже одного PalindromManager — но даже если так, то в 99% окажется, что один из классов полностью включает в себя функциональность другого. Тогда мы выкидываем более убогий вариант, и продолжаем пользоваться полным.





PD>Эхе-хе. Мы же не договариваемся, мы же члены разных команд. Я же о твоих действиях ничего не знаю. Вот и сделаю я PalindromHelper и ConversionHelper и т.д. А ты, ничего об мне не зная, свои такие (да нет, не такие, а несколько иные) соорудишь. Иван о нас тоже не знает, он свои сделает. В каждом из них чего-то не хватать будет, а что-то не лучшим образом сделано будет. Было бы наследование — не стал бы я свой хелпер делать, зная о том, что твой сущетсвует, а попробовал бы его улучшить. А ты потом мой. А Иван твой.

Противоречия выделены. Попробуй подумать на ту же тему еще раз.


PD>Э нет, не все так просто. См выше о PalindromHelper и BestPalindromHelper. Впрочем, хелперы уберем, вернемся к классу. В итоге получится класс CSuperString, в котором сделано именно лучшим образом. И вскоре всем становится известно, что лучшего средства для работы со строками, чем этот CSuperString, и не существует. Ссылок на него море , все его любят и за него голосуют , все им довольны и используют.

Пока что не видно, каким образом получится этот класс, если его разрабатывает не одна команда, а несколько несвязанных.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[30]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 24.12.08 05:59
Оценка: :)
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>> А поэтому такая оценка (рейтинга) дает основание делать выводы о популярности ресурса.

IB>Однако популярность ресурса не дает основания делать выводы о качестве выложенных там материалов и тем более о качестве какого либо конкретного материала.

Извини, но не согласен. О качестве конкретного материала — да, а о качестве ресурса — дает основание делать вывод.


IB>Так что Павел, прекращай заниматься подменой понятий.


Я ничего не подменяю. Я нигде не утверждал, что CStingEx — высококачественный продукт, я его и не смотрел всерьез вообще-то. Я его просто привел как пример того, что такое возможно. Вот и все.

PD>>Как практику — критерий истины

IB>Данная практика подтверждает, что кривой код существует — это истина.

А не мог ли уважаемый оппонет дать хоть какой-нибудь критерий, позволяющий отличать кривой код от не-кривого ? У меня, например, есть основание утверждать, что код, реализующий litview в .NET — кривой.

S>>>Павел, это несеръезно. Такого поиска в природе не бывает. Реальный разработчик будет искать не класс, а функциональность. Если нужны палиндромы — будут искать palindrome, а не всех мыслимых наследников от строки.

PD>>Нет, это очень даже серьезно. Попробуй поискать на google "palindrome" и у тебя сразу настроение испортится.
IB>

IB>...
IB>If you reflect a bit and are honest with yourself, you'll admit that you have this alleged inconsistency with all the nontrivial classes you use, because no class has every function desired by every client. Every client adds at least a few convenience functions of their own, and these functions are always non-members. C++ programers are used to this, and they think nothing of it. Some calls use member syntax, and some use non-member syntax. People just look up which syntax is appropriate for the functions they want to call, then they call them. Life goes on. It goes on especially in the STL portion of the Standard C++ library, where some algorithms are member functions (e.g., size), some are non-member functions (e.g., unique), and some are both (e.g., find). Nobody blinks. Not even you.

IB>(c)Scott Meyers

Я что-то не пойму, зачем ты это мне второй раз привел. Да, в С++ статические функции можно вызывать через точку или двоеточие. ИМХО зря. Ну и что ?

IB>В том-то и дело, что хелперы лучше, в том числе и потому, что в них гораздо проще разобраться. Тут один товарищь в соседнем флейме, тоже отстаивая позицию "тру ООП", так распихал методы по классам, что при всем желании не найдешь. А ты предлагаешь еще это все и в иерархию запихнуть. Как показывает твоя любимая практика, набор хелперов в этом плане гораздо уобнее.


Подумал сам еще раз над вашими аргументами.

ИМХО здесь некие понятия смешаны в одну кучу и говорим мы о разных вещах. Отсюда, может быть, и возинкает непонимание и несогласие.

Вот Антон привел мне регэкс и говорит — зачем его в стринг пихать, не место ему там. Согласен. не место. Но!

Представь себе, что ни стринга, ни регэкспа нет вообще. Новый язык, и тебе поручено создать для него и стринги и регэкспы.

Варианты

1. class string, class regexp
2. class string, class regexpstring : string

Какой лучше ? Ты явно за первый. Я тоже.

Здесь вопрос-то не о наследовании, а о добавлении новой функциональности. Регекспы, конечно, со стрингами работают, но они отнюдь не часть стринга. Много чего еще можно придумать, что со стрингами работать будет. Например, class russianword, со всякими склонениями и спряжениями. Едва ли стоит такую фунциональность в стринг пихать, хелпер явно лучше.

Но есть и другое. Вот сделал ты (не ты, MS) CString. А теперь посмотри CStringEx. Не будем сейчас обсуждать качество реализации, возьмем идею — зачем сделано. Оказывается, чтобы улучшить существующую функциональность. Если в твоем классе string есть поиск вперед, а поиск назад почему-то отсутствует, так что приходится ревертировать строки для такого поиска — что плохого, если я напишу наследника, который этот поиск назад будет делать ?

Естественный вопрос — а где граница ? Да, улучшая поиск, можно и до регекспов дойти, и до trie-деревьев, и до хешей. Ответа точного, естественно, нет, но его и вообще нет. Если бы ты string и regexp делал бы сам — почему ты не уложил бы regexp внутрь стринга ? По-видимому. из неких соображений, связанных с OOD. Ну вот и здесь так же.

PD>>вы получите фактически возврат к языку С, так как каждый из ваших хелперов, если они static, по существу представляет собой набор отдельных функций, объединенных именем класса.

IB>Хоть горшком назови.. Ты воспринимаешь наследование, как средство организации кода, но оно для этого не предназначено и никогда не было.

Так-таки никогда ? А как же быть с наследованием от Control и т.д. Ты же не в неймспейс , где Control, это помещаешь, а в свой неймспейс, да с наследованием. Или это не есть организация кода ? Тогда какая тут организация ?

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

IB>Для того чтобы логически группировать код — есть неймспейсы, вот их и используй.

Я бы согласился с этим, если бы они употреблялись именно с этой целью. Увы, они слишком общие. Это во-первых. А во-вторых, может, я не прав, но вроде бы не принято лезть со своими классами/методами в чужой неймспейс ? Как посмотрят люди, если я захочу кое-что добавить к System.Drawing ?
With best regards
Pavel Dvorkin
Re[30]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 24.12.08 06:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>Это есть некая подмена понятий, довольно-таки тонкая.
S>Павел, никакой подмены понятий нет. Как только ты начинаешь привлекать к рассмотрению популярность, ты выходишь за рамки технической дискуссии.

Очень спорно. Если речь идет о популярности ресурса, и ресурс дейсивительно популярен (а это факт) — это означает, что качество техническое там для многих продуктов неплохое.

S>Совершенно неважно, явно ли проводится голосование, или по посещаемости, или по подсчету ссылок на ресурс — в любом случае речь идет о популярности. Которая может определяться техническим совершенством, а может — массовым заблуждением.


А вот это не аргумент вообще. Отвергаю полностью. Если ты будешь говорить о массовых заблуждениях в области политики или психологии — можно и обсуждать. Но здесь речь идет о технической области. Никаких оснований утверждать , что все те, кто придерживаются некоего подхода, который тебе не нравится, массово заблуждаются, у тебя нет. С таким же успехом можно заявить, что массовые заблуждения у противоположной стороны. И ни то, ни другое не доказать и не отвергнуть. Потому что практика — критерий истины, а практика есть и за ту, и за другую сторону. Так что на этом пути можно только пустословием и голословными обвинениями заниматься.

PD>>С помощью софистики можно доказать все, что угодно. Не ты ли в свое время заявил, что правктика — критерий истины ? Я тебе привожу примеры этой самой практики, эти примеры не по моему заказу сделаны, они исходно существуют. Теперь тебя эти примеры (эта практика) не устраивают, они вдруг оказываются голосованием, к которому у тебя отрицательное отношение. Так разберись все же, является практика критерием или нет.

S>А вот тут происходит тонкая подмена понятий. Вместо практики, как примеров реального применения с иллюстрацией реального преимущества, приводится популярность. Ты сначала разберись с тем, является ли популярность связанной с качеством, или нет.

А популярность, вообще-то, именно отражает практику, то есть примеры реального применения и т.д. Мы же не за ЛДПР голосуем тут. Если есть продукт и его используют, причем грамотные люди, это и значит, что он востребован, что он лучший на данный момент, то есть качественный. Ну с какой стати я буду в своих программах некачественные компонентиы использовать ?

Так что связана, да. Может, не на 100%. Не линейно зависит, но коррелирует.


PD>>Я здесь заявляю, что утверждение, будто любой код оттуда — жемчужина , мне приписывать не надо, и требую ссылку, где я такое якобы заявлял. Ссылку ты не даешь (ее в природе не существует), а вместо этого заявляешь, что якобы я считаю наличие одного какого-то класса нормой. Хот я ясно, кажется, сказал, что не идет речь о любом коде. Как это называть ?

S>Это называть — типичными для тебя попытками вывернуться наизнанку, лишь бы не признавать своих заблуждений.
S>Если твои аргументы не относились к классу CStringEx, то давай их просто выбросим как нерелевантные и всё. Поскольку ты избегаешь прямолинейных утверждений, мне приходится догадываться, что именно ты имел в виду. Вот ты привлек (1)популярность (2)всего ресурса к обоснованию правильности одного конкретного класса.

Ссылку в студию, please, где я писал про "правильность одного конкретного класса". Нет такого. Я его привел как пример некоего подхода, и не больше. А правильный он или нет (==качественный) — не знаю, я и не смотрел-то всерьез его.

>Как мне это трактовать? Как демагогию? В одном посте применено сразу три демагогических приема.


Трактуй как хочешь, но сначала ссылку дай.

PD>>Как практику — критерий истины

S>Ну так ведь практики-то нет!

"Что же у вас, чего ни хватишься, ничего нет ?" (C) М. Булгаков


S>Это понятно. Поясняю еще раз, специально для тех, кто не знает, что такое Single Responsibility Principle:

S>Два хелпера, написанные для разных целей, никогда не будут пересекаться по функциональности.
S>Не может быть такого, чтобы в PalindromManager был метод .GetBytesCount, а в Encoding — .IsPalindrome.
S>Я вижу, что с пониманием этого у тебя проблемы. Ты вот в качестве примеров привел классы с характерными именами — Dvorkin и Sinclair. Это показывает, что ты трактуешь класс как помойку с методами, классифицированную как угодно, кроме функциональности.

См. мой ответ IB. Я там на этот вопрос ответил. Мы о разных вещах говорим, похоже.

S>Я предлагаю делить хелперы не по имени автора или еще чему-нибудь, а по Responsibility.


Во-во. Именно о разных вещах.






PD>>Эхе-хе. Мы же не договариваемся, мы же члены разных команд. Я же о твоих действиях ничего не знаю. Вот и сделаю я PalindromHelper и ConversionHelper и т.д. А ты, ничего об мне не зная, свои такие (да нет, не такие, а несколько иные) соорудишь. Иван о нас тоже не знает, он свои сделает. В каждом из них чего-то не хватать будет, а что-то не лучшим образом сделано будет. Было бы наследование — не стал бы я свой хелпер делать, зная о том, что твой сущетсвует, а попробовал бы его улучшить. А ты потом мой. А Иван твой.

S>Противоречия выделены. Попробуй подумать на ту же тему еще раз.

Да, неточно выразился. Исправляю.

PD>>Эхе-хе. Мы же не договариваемся, мы же члены разных команд. Я же о твоих действиях ничего не знаю. Вот и сделаю я PalindromHelper и ConversionHelper и т.д. А ты, ничего об мне не зная, свои такие (да нет, не такие, а несколько иные) соорудишь. Иван о нас тоже не знает, он свои сделает. В каждом из них чего-то не хватать будет, а что-то не лучшим образом сделано будет. И вот три хелпера сделаны, и каждый свой недостаток имеет. Теперь я узнал про твой. Он вроде лучше, чем мой, но в нем кое-чего, по моему мнению не хватает (или не так сделано). В общем, я за твой, но хочу в него кое-что из своего добавить. Далее по тексту.



PD>>Э нет, не все так просто. См выше о PalindromHelper и BestPalindromHelper. Впрочем, хелперы уберем, вернемся к классу. В итоге получится класс CSuperString, в котором сделано именно лучшим образом. И вскоре всем становится известно, что лучшего средства для работы со строками, чем этот CSuperString, и не существует. Ссылок на него море , все его любят и за него голосуют , все им довольны и используют.

S>Пока что не видно, каким образом получится этот класс, если его разрабатывает не одна команда, а несколько несвязанных.

Ну я вроде объяснил.
With best regards
Pavel Dvorkin
Re[31]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.12.08 06:33
Оценка: 15 (1) +1
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Извини, но не согласен. О качестве конкретного материала — да, а о качестве ресурса — дает основание делать вывод.
А нас качество ресурса вообще не интересует. Это ты начал доказывать, что он замечательный, в контексте разговора о качестве конкретных классов.

IB>>Так что Павел, прекращай заниматься подменой понятий.


PD>Я ничего не подменяю. Я нигде не утверждал, что CStingEx — высококачественный продукт, я его и не смотрел всерьез вообще-то. Я его просто привел как пример того, что такое возможно. Вот и все.

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

PD>А не мог ли уважаемый оппонет дать хоть какой-нибудь критерий, позволяющий отличать кривой код от не-кривого ? У меня, например, есть основание утверждать, что код, реализующий litview в .NET — кривой.

Тебе уже написали этот критерий несколько раз. Некривой код библиотеки — это такой, который позволяет писать пользовательский код короче и с меньшим количеством ошибок. Поэтому "проверяльщик на палиндромы", который требует, к примеру, сабклассинга TextBox — кривой.

PD>Подумал сам еще раз над вашими аргументами.

Это хорошо.
PD>ИМХО здесь некие понятия смешаны в одну кучу и говорим мы о разных вещах. Отсюда, может быть, и возинкает непонимание и несогласие.

PD>Здесь вопрос-то не о наследовании, а о добавлении новой функциональности. Регекспы, конечно, со стрингами работают, но они отнюдь не часть стринга.

Правильно! Не часть. Single Responsibility Principle.
PD>Много чего еще можно придумать, что со стрингами работать будет. Например, class russianword, со всякими склонениями и спряжениями. Едва ли стоит такую фунциональность в стринг пихать, хелпер явно лучше.
Правильно.

PD>Но есть и другое. Вот сделал ты (не ты, MS) CString. А теперь посмотри CStringEx. Не будем сейчас обсуждать качество реализации, возьмем идею — зачем сделано.

Да, давай обсудим идею.
PD>Оказывается, чтобы улучшить существующую функциональность. Если в твоем классе string есть поиск вперед, а поиск назад почему-то отсутствует, так что приходится ревертировать строки для такого поиска — что плохого, если я напишу наследника, который этот поиск назад будет делать ?
Еще раз: плохо то, что такой наследник накладывает совершенно лишние требования на использующий его код. Ты не можешь выполнить поиск назад по любой строке. Для использования этого наследника нужно обязательно сменить тип существующей строки, полученной от стороннего кода.
Ты попробуй сесть и написать пример приложения, которое пользуется этим поиском назад. И ты быстро поймешь, что
а) этот пример получается компактнее, если использовать внешний хелпер
б) либо он получается такой же, но для этого нужно написать очень-очень толстый CStringEx.
Я тебе уже приводил пример с классом CMsg, где функционал, для которого достаточно однострочной функции, реализуется через целый отдельный класс.

PD>Естественный вопрос — а где граница ? Да, улучшая поиск, можно и до регекспов дойти, и до trie-деревьев, и до хешей. Ответа точного, естественно, нет, но его и вообще нет.

Ну конечно же ответ есть. Правило большого пальца:

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

Вот тебе и граница.
PD>Если бы ты string и regexp делал бы сам — почему ты не уложил бы regexp внутрь стринга ? По-видимому. из неких соображений, связанных с OOD. Ну вот и здесь так же.
Эти соображения очень просты: нужно всегда писать так, чтобы пользоваться библиотекой было удобно. Вначале карьеры архитектору тяжело в уме прикинуть все случаи использования. Поэтому у него есть два средства:
1. Писать прототипы прикладного кода для типичных случаев, сравнивая их характеристики
2. Пользоваться эвристиками, вроде той, которую я процитировал
3. Помнить о том, что 2 — это всего лишь эвристика для 1. Поэтому иногда 1 может потребовать отойти от 1.

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

PD>Так-таки никогда ? А как же быть с наследованием от Control и т.д. Ты же не в неймспейс , где Control, это помещаешь, а в свой неймспейс, да с наследованием. Или это не есть организация кода ? Тогда какая тут организация ?

Неймспейс = организация кода. Наследование != организация кода. Что тут непонятно?

PD>Я бы согласился с этим, если бы они употреблялись именно с этой целью. Увы, они слишком общие. Это во-первых. А во-вторых, может, я не прав, но вроде бы не принято лезть со своими классами/методами в чужой неймспейс ? Как посмотрят люди, если я захочу кое-что добавить к System.Drawing ?

А зачем тебе лезть в чужой неймспейс? Лезь в свой. Вот, к примеру, ты не обратил внимание, что методы из System.Text относятся вроде бы ко строкам, но не запиханы в System?
Или что GZipStream помещен не в System.IO, а в System.IO.Compression?
Ну так вот обрати.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[31]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.12.08 06:50
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Очень спорно. Если речь идет о популярности ресурса, и ресурс дейсивительно популярен (а это факт) — это означает, что качество техническое там для многих продуктов неплохое.
Нет. Это не так. И даже если бы это было в целом так, это бы не означало, что любой взятый оттуда пример является образцом технического качества.
Это непонятно?

PD>А вот это не аргумент вообще. Отвергаю полностью. Если ты будешь говорить о массовых заблуждениях в области политики или психологии — можно и обсуждать. Но здесь речь идет о технической области. Никаких оснований утверждать , что все те, кто придерживаются некоего подхода, который тебе не нравится, массово заблуждаются, у тебя нет.

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

PD>А популярность, вообще-то, именно отражает практику, то есть примеры реального применения и т.д. Мы же не за ЛДПР голосуем тут. Если есть продукт и его используют, причем грамотные люди, это и значит, что он востребован, что он лучший на данный момент, то есть качественный. Ну с какой стати я буду в своих программах некачественные компонентиы использовать ?

Покажи мне грамотных людей, которые используют CStringEx.

PD>Ссылку в студию, please, где я писал про "правильность одного конкретного класса". Нет такого. Я его привел как пример некоего подхода, и не больше. А правильный он или нет (==качественный) — не знаю, я и не смотрел-то всерьез его.

Тогда зачем приводить некачественный пример в качестве оправдания практики наследования от класса строки?

PD>"Что же у вас, чего ни хватишься, ничего нет ?" (C) М. Булгаков

Так это у тебя нет. Я спрашивал — зачем наследоваться от строки? Ты привел пример. Тебе ответили, что пример плохой. Ты начал доказывать, что раз он опубликован на модном ресурсе, значит всё в порядке.


PD>>>Эхе-хе. Мы же не договариваемся, мы же члены разных команд. Я же о твоих действиях ничего не знаю. Вот и сделаю я PalindromHelper и ConversionHelper и т.д. А ты, ничего об мне не зная, свои такие (да нет, не такие, а несколько иные) соорудишь. Иван о нас тоже не знает, он свои сделает. В каждом из них чего-то не хватать будет, а что-то не лучшим образом сделано будет. И вот три хелпера сделаны, и каждый свой недостаток имеет. Теперь я узнал про твой. Он вроде лучше, чем мой, но в нем кое-чего, по моему мнению не хватает (или не так сделано). В общем, я за твой, но хочу в него кое-что из своего добавить. Далее по тексту.

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

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

PD>Ну я вроде объяснил.

Забавная теория. На практике мы почему-то видим несколько классов CStringEx, которые друг о друге ничего не знают. Если бы это были хелперы, то разработчик-прикладник мог бы пользоваться всей функциональностью без переделок. Увы, для наследников ему придется вручную объединять эти классы.
Понятно, что это непроизводительная работа?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[29]: Override для произвольного метода.
От: LaPerouse  
Дата: 24.12.08 07:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, 4058, Вы писали:

PD>Что же, я с уважением готов относиться практически к любому чужому убеждению. Но все же останусь при своем

Если тебе так нравится MFC, советую обратить внимание на wxWidgets. Там тот же принцип (вместо виртуальных функций прямое связывание через макросы) и похожая архитектура. Но сделана, в отличие от MFC, более-менее по-человечески. Хотя с GUI-бибилотеками Java, которые в отличие от этих двух библиотек были спроектированы профессионалами, все равно конечно не сравнить.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[31]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 24.12.08 11:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Извини, но не согласен. О качестве конкретного материала — да, а о качестве ресурса — дает основание делать вывод.

Оставим качество ресурса в покое, не это тема дискуссии, хотя утверждение тоже весьма спорное.
Значит с тем, что пример не к селу ни к городу ты согласен?

PD>Я ничего не подменяю. Я нигде не утверждал, что CStingEx — высококачественный продукт, я его и не смотрел всерьез вообще-то. Я его просто привел как пример того, что такое возможно. Вот и все.

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

PD>А не мог ли уважаемый оппонет дать хоть какой-нибудь критерий, позволяющий отличать кривой код от не-кривого ?

Данный аспект мы уже обсудили выше.

PD>У меня, например, есть основание утверждать, что код, реализующий litview в .NET — кривой.

Охотно верю. WinForms (равно как и Web) местами вообще отличаются редкостной кривизной. Но какое это имеет отношение к данной дискуссии?

PD>Я что-то не пойму, зачем ты это мне второй раз привел.

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

PD>Но есть и другое. Вот сделал ты (не ты, MS) CString. А теперь посмотри CStringEx. Не будем сейчас обсуждать качество реализации, возьмем идею — зачем сделано. Оказывается, чтобы улучшить существующую функциональность. Если в твоем классе string есть поиск вперед, а поиск назад почему-то отсутствует, так что приходится ревертировать строки для такого поиска — что плохого, если я напишу наследника, который этот поиск назад будет делать ?

Ровно тоже самое, плохость никуда не делась. Там уже Антон все довольно подробно расписал... Могу лишь процитировать того же Меерса — "To put it bluntly, non-member functions happen..."

PD>Естественный вопрос — а где граница ? Да, улучшая поиск, можно и до регекспов дойти, и до trie-деревьев, и до хешей. Ответа точного, естественно, нет, но его и вообще нет. Если бы ты string и regexp делал бы сам — почему ты не уложил бы regexp внутрь стринга ? По-видимому. из неких соображений, связанных с OOD. Ну вот и здесь так же.

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

PD>Так-таки никогда ? А как же быть с наследованием от Control и т.д. Ты же не в неймспейс , где Control, это помещаешь, а в свой неймспейс, да с наследованием. Или это не есть организация кода ? Тогда какая тут организация ?

От Control-а нужно наследоваться потому, что библиотеку задизайнили не лучшим образом и заиспользовали полиморфизм через наследование реализации. Таким образом, ответ на твой вопрос — да, это не организация кода, а полиморфизм, в не самом лучшем своем проявлении.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[32]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 25.12.08 06:10
Оценка: :))
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>Извини, но не согласен. О качестве конкретного материала — да, а о качестве ресурса — дает основание делать вывод.
S>А нас качество ресурса вообще не интересует. Это ты начал доказывать, что он замечательный, в контексте разговора о качестве конкретных классов.

Да, начал.


PD>>Я ничего не подменяю. Я нигде не утверждал, что CStingEx — высококачественный продукт, я его и не смотрел всерьез вообще-то. Я его просто привел как пример того, что такое возможно. Вот и все.

S>Ну, если как следует вспомнить ход беседы, то окажется, что ты доказывал необходимость наследования от класса строки на примере CStringEx.

Возможность, а не необходимость.

S>Тебе уже написали этот критерий несколько раз. Некривой код библиотеки — это такой, который позволяет писать пользовательский код короче


Для меня абсолютно несущественно, короче или нет. Для меня существенно — эффективнее или нет. Ради нее я готов написать в 5 раз больше текста. Критерий не принимается.

>и с меньшим количеством ошибок.


Критерий совершенно кривой сам. Сколько будет ошибок — зависит от того, кто писать будет.

А вот о качестве кода ты ничего не сказал. Из этого следует, что код, который позволяет писать "короче и с меньшим...", но внутри себя реализован так, что хоть святых выноси, а чтобы его не попробовали расширить, установлен как sealed — не есть кривой ? Да или нет ?

> Поэтому "проверяльщик на палиндромы", который требует, к примеру, сабклассинга TextBox — кривой.


А по моему критерию код, который для сортировки листвью его пересоздает — не просто кривой, а вообще загогулина какая-то.


PD>>Но есть и другое. Вот сделал ты (не ты, MS) CString. А теперь посмотри CStringEx. Не будем сейчас обсуждать качество реализации, возьмем идею — зачем сделано.

S>Да, давай обсудим идею.
PD>>Оказывается, чтобы улучшить существующую функциональность. Если в твоем классе string есть поиск вперед, а поиск назад почему-то отсутствует, так что приходится ревертировать строки для такого поиска — что плохого, если я напишу наследника, который этот поиск назад будет делать ?
S>Еще раз: плохо то, что такой наследник накладывает совершенно лишние требования на использующий его код. Ты не можешь выполнить поиск назад по любой строке. Для использования этого наследника нужно обязательно сменить тип существующей строки, полученной от стороннего кода.

Разумееется.

S>Ты попробуй сесть и написать пример приложения, которое пользуется этим поиском назад. И ты быстро поймешь, что

S>а) этот пример получается компактнее, если использовать внешний хелпер

А нельзя ли последнее утверждение обосновать. Докажи, что он будет компактнее. Вот конкретно

class DString // уже готов, но в нем нет поиска назад

class D1String : DString // в нем будет добавлен поиск назад

class HString // а это твой хелпер

ну вот и докажи.

S>б) либо он получается такой же, но для этого нужно написать очень-очень толстый CStringEx.


Писать что в наследнике, что в хелпере придется одно и то же — обертку над strrchr.

PD>>Естественный вопрос — а где граница ? Да, улучшая поиск, можно и до регекспов дойти, и до trie-деревьев, и до хешей. Ответа точного, естественно, нет, но его и вообще нет.

S>Ну конечно же ответ есть. Правило большого пальца:
S>

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

S>Вот тебе и граница.

Ну что же, давай обсудим. Объясни с этой точки зрения, почему прямой поиск не надо было выносить во внешний код, а обратный поиск (коль скоро его в базовом классе нет) — надо.
Второй аналогичный вопрос. Почему в классе Directory метод GetFiles как он сейчас есть, должен быть в этом классе, а метод GetNextFile (реализующий по сути ту же функциональность , но по другому — надо ? А если бы ее MS реализовала сама внутри нынешнего Directory (ей-то ничто не мешало это сделать!) — то не надо ?

Вот можешь прямо на эти два примера ответить ?




PD>>Если бы ты string и regexp делал бы сам — почему ты не уложил бы regexp внутрь стринга ? По-видимому. из неких соображений, связанных с OOD. Ну вот и здесь так же.

S>Эти соображения очень просты: нужно всегда писать так, чтобы пользоваться библиотекой было удобно. Вначале карьеры архитектору тяжело в уме прикинуть все случаи использования. Поэтому у него есть два средства:
S>1. Писать прототипы прикладного кода для типичных случаев, сравнивая их характеристики
S>2. Пользоваться эвристиками, вроде той, которую я процитировал
S>3. Помнить о том, что 2 — это всего лишь эвристика для 1. Поэтому иногда 1 может потребовать отойти от 1.

S>Ну, а после некоторой практики, вырабатывается интуиция, подсказывающая, как действовать. Твоя ошибка в том, что ты считаешь интуицию самостоятельным источником для принятия решений. А на самом деле интуиция — всего лишь невербальное обобщение практического опыта.


+1. Но все это не суть важно, интуиция или что-то еще. Важно одно — есть некие соображения о делении на классы.

PD>>Так-таки никогда ? А как же быть с наследованием от Control и т.д. Ты же не в неймспейс , где Control, это помещаешь, а в свой неймспейс, да с наследованием. Или это не есть организация кода ? Тогда какая тут организация ?

S>Неймспейс = организация кода. Наследование != организация кода. Что тут непонятно?

Я просто с этим не согласен. Наследование несет на себе много всякого, в том числе и организацию кода тоже. ИМХО.
With best regards
Pavel Dvorkin
Re[32]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 25.12.08 06:31
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Извини, но не согласен. О качестве конкретного материала — да, а о качестве ресурса — дает основание делать вывод.

IB>Оставим качество ресурса в покое, не это тема дискуссии, хотя утверждение тоже весьма спорное.
IB>Значит с тем, что пример не к селу ни к городу ты согласен?

Нет

IB>Вот это и есть подмена понятий.. Уже несколько раз было сказано, что с тем что такое в принципе возможно и некоторые товарищи так делают — никто не спорит. Речь идет не об этом, а о том, что так делать нельзя и надо делать по другому. Не стоит использовать наследование как средство группировки кода. И тот факт, что кто-то так делает, совершенно не является аргументом в пользу того, что так делать надо.


Ну что же, ясно, впрочем, и изначално ясно было. Я с этим не согласен. Вот и все.

PD>>А не мог ли уважаемый оппонет дать хоть какой-нибудь критерий, позволяющий отличать кривой код от не-кривого ?

IB>Данный аспект мы уже обсудили выше.

Можно ссылку ? Не помню, чтобы мы с тобой это обсуждали. Склероз...

PD>>У меня, например, есть основание утверждать, что код, реализующий litview в .NET — кривой.

IB>Охотно верю. WinForms (равно как и Web) местами вообще отличаются редкостной кривизной. Но какое это имеет отношение к данной дискуссии?

Просто если он кривой, то тогда он такой же аргумент, как и CStringEx

IB>Здесь речь как раз о том, что совершенно без разницы где находится функция — в хелпере или в том же классе. При поиске функциональности разработчик ищет прежде всего функциональность, а не класс, который по идее должен ее реализовывать.


-1.


PD>>Естественный вопрос — а где граница ? Да, улучшая поиск, можно и до регекспов дойти, и до trie-деревьев, и до хешей. Ответа точного, естественно, нет, но его и вообще нет. Если бы ты string и regexp делал бы сам — почему ты не уложил бы regexp внутрь стринга ? По-видимому. из неких соображений, связанных с OOD. Ну вот и здесь так же.

IB>Конечно же есть. Есть очень хорошее правило большего пальца: Если функционал метода можно реализовать только с помощю публичного контракта класса, значит он должен находиться вне класса.

См. ответ Антону . Как бы все это свести, чтобы мне не приходилось то ему, то тебе отвечать ? Может, вы с ним будете мне коллективно отвечать ?

PD>>Так-таки никогда ? А как же быть с наследованием от Control и т.д. Ты же не в неймспейс , где Control, это помещаешь, а в свой неймспейс, да с наследованием. Или это не есть организация кода ? Тогда какая тут организация ?

IB>От Control-а нужно наследоваться потому, что библиотеку задизайнили не лучшим образом и заиспользовали полиморфизм через наследование реализации. Таким образом, ответ на твой вопрос — да, это не организация кода, а полиморфизм, в не самом лучшем своем проявлении.

Слишком уж серьезно это не самое лучшее проявление. Убери класс CStringEx — в общем, никто и не почешется, напишем иной. А вот выкинь это наслелование с полиморфизмом — и не останется в .Net никакого GUI, одни консольные приложения писать будем А впрочем, и в Delphi, и в MFC, да и в Яве ИМХО (никогда в яве GUI не писал, так что не уверен). Все они нарушают этот ваш фундаментальный принцип, все используют наследование. Как-то это плохо вяжется с фундаментальностью принципа. Аргумент насчет не лучшего дизайна не приму — почему во всех библиотеках этот не лучший дизайн используется ?

И еще один вопрос к тебе, извини уж за его наивность . Как я понимаю, все твои возражения по наследованию относятся к тому варианту, когда некое третье лицо (фирма) начинает наследовать от не своего кода , так ? В пределах одной библиотеки ты, надеюсь, не против наследования ? Очевидно, не против, иначе тебе придется всю .Net похоронить. Так вот, вопрос такой. Пусть есть некий класс, сделанный фирмой X в составе библиотеки L версии 1. Имеет ли право фирма X в библиотеке Y версии 2 сделать наследника от этого класса ? Имеет ли право на это фирма X1, которая купила фирму X между выходами версий 1 и 2 ? Имеет ли право на это фирма Z, которая никакого отношения к X не имеет, но фирма X прекратила свое существование и перед смертью сделала все свои коды открытыми ?
With best regards
Pavel Dvorkin
Re[33]: Override для произвольного метода.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 25.12.08 06:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

>>и с меньшим количеством ошибок.

PD>Критерий совершенно кривой сам. Сколько будет ошибок — зависит от того, кто писать будет.

Статистика показывает что средняя плотность ошибок в программах на тыщу строк кода не зависит от языка.
Если писать будет больше чем один человек, то стоит использовать средства позволяющие писать меньше кода.
Re[32]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 25.12.08 06:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>Очень спорно. Если речь идет о популярности ресурса, и ресурс дейсивительно популярен (а это факт) — это означает, что качество техническое там для многих продуктов неплохое.
S>Нет. Это не так. И даже если бы это было в целом так, это бы не означало, что любой взятый оттуда пример является образцом технического качества.
S>Это непонятно?

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

PD>>А вот это не аргумент вообще. Отвергаю полностью. Если ты будешь говорить о массовых заблуждениях в области политики или психологии — можно и обсуждать. Но здесь речь идет о технической области. Никаких оснований утверждать , что все те, кто придерживаются некоего подхода, который тебе не нравится, массово заблуждаются, у тебя нет.

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

Да, не хочу, не убеждают они меня. И других тоже.

Давай в иную плоскость это тогда переведем. Я утверждаю нечто, ты утверждаешь противоположное. За мной некая практика, за тобой тоже. Но ты еще вдруг утверждать начинаешь, что моя , мол, практика — это результат массового заблужденмя. Обоснуй критерии, которые дают тебе право такое утверждать. В общем виде, вне применения к данной проблеме потомков класса. Потому что без таких критериев остается только один аргумент — "по этому вопросу есть два мнения, одно мое, другое неправильное".


PD>>А популярность, вообще-то, именно отражает практику, то есть примеры реального применения и т.д. Мы же не за ЛДПР голосуем тут. Если есть продукт и его используют, причем грамотные люди, это и значит, что он востребован, что он лучший на данный момент, то есть качественный. Ну с какой стати я буду в своих программах некачественные компонентиы использовать ?

S>Покажи мне грамотных людей, которые используют CStringEx.

Ну опять Ей- богу, несерьезно. Ты прекрасно знаешь, что в C++ исходники промышленных продуктов никто не показывает. Поэтому показать тебе, кто и какое наследование в промышленных продуктах использует, я никак не могу. А пример Wordpad и его классы я приводил.

А вообще пора заканчивать эту дискуссию. Как говорится, позиции сторон ясны.
With best regards
Pavel Dvorkin
Re[33]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 25.12.08 07:12
Оценка: 1 (1) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Для меня абсолютно несущественно, короче или нет. Для меня существенно — эффективнее или нет. Ради нее я готов написать в 5 раз больше текста. Критерий не принимается.

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

PD>Критерий совершенно кривой сам. Сколько будет ошибок — зависит от того, кто писать будет.

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

PD>А вот о качестве кода ты ничего не сказал. Из этого следует, что код, который позволяет писать "короче и с меньшим...", но внутри себя реализован так, что хоть святых выноси, а чтобы его не попробовали расширить, установлен как sealed — не есть кривой ? Да или нет ?

Нет, почему. При прочих равных код, сам написанный "короче и с меньшим...", лучше "хоть святых выноси".
Но это при прочих равных. Если код сам по себе написан замечательно, но требует от прикладного программиста большого объема работы и высокой дисциплины, то он однозначно кривее, чем код, которым легко пользоваться.

PD>А по моему критерию код, который для сортировки листвью его пересоздает — не просто кривой, а вообще загогулина какая-то.

С этим никто не спорил.

PD>Разумееется.



PD>А нельзя ли последнее утверждение обосновать. Докажи, что он будет компактнее. Вот конкретно


PD>class DString // уже готов, но в нем нет поиска назад


PD>class D1String : DString // в нем будет добавлен поиск назад


PD>class HString // а это твой хелпер


PD>ну вот и докажи.

Ну, ок. Поскольку DSting — это класс из стандартной библиотеки, все сторонние библиотеки построены на нем. В частности, есть, допустим, метод DString HttpRequest::GetParameter(DString paramName).

Вот простейший фрагмент кода, который ищет последнее вхождение одного параметра в другом:

int GetLastPos(HttpRequest &request)
{
  return HString::ReverseFind(request.GetParameter("one"), request.GetParameter("two"));
}

Здесь используется два факта:
1. У DString есть конструктор от char*, благодаря чему в него легко кормить константы.
2. HString::ReverseFind принимает аргументы типа DString
Давай перепишем его с применением твоего наследника:
int GetLastPos(HttpRequest &request)
{
  DlString temp = request.GetParameter("one"); // Здесь мы вынуждены создать копию строки, что вряд ли скажется позитивно на производительности
    return temp.ReverseFind(request.GetParameter("two"));
}

Это я еще предположил, что наследник писался в расчете на то, что в параметре ReverseFind ему передадут DStirng, а не DlString.
Итого мы имеем создание лишнего экземпляра и дополнительную строчку кода. Мы, конечно, можем и этот код записать в одну строку, но тем не менее останется лишний вызов конструктора:
int GetLastPos(HttpRequest &request)
{
  DlString temp =  // Здесь мы вынуждены создать копию строки, что вряд ли скажется позитивно на производительности
    return DlString(request.GetParameter("one")).ReverseFind(request.GetParameter("two"));
}

Это, Павел, самый-самый примитивный пример. Как только речь зайдет о чем-то более интересном, окажется, что плата за использование наследника еще возрастёт.

PD>Писать что в наследнике, что в хелпере придется одно и то же — обертку над strrchr.

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

PD>Ну что же, давай обсудим. Объясни с этой точки зрения, почему прямой поиск не надо было выносить во внешний код, а обратный поиск (коль скоро его в базовом классе нет) — надо.

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

PD>Второй аналогичный вопрос. Почему в классе Directory метод GetFiles как он сейчас есть, должен быть в этом классе, а метод GetNextFile (реализующий по сути ту же функциональность , но по другому — надо ? А если бы ее MS реализовала сама внутри нынешнего Directory (ей-то ничто не мешало это сделать!) — то не надо ?

Поясняю еще раз: по-хорошему, с самого начала должен был быть ровно один метод — тот, который возвращает ленивый список — IEnumerable<string>/IEnumerable<FileSystemInfo>.
Но в реальной жизни мы имеем дело с реальными программистами. Невозможно с первого раза реализовать идеальную библиотеку. Но есть способ дать возможность расширения библиотеки. Эта возможность — есть. Никакого unsealed она не требует.

PD>+1. Но все это не суть важно, интуиция или что-то еще. Важно одно — есть некие соображения о делении на классы.

Важно то, что ничего сверхъестественного в этих соображениях нет. Им можно научить любого человека, если он перестанет кочевряжиться и начнет думать головой.

PD>Я просто с этим не согласен. Наследование несет на себе много всякого, в том числе и организацию кода тоже. ИМХО.

Наследование нужно ровно для двух вещей:
1. Полиморфизм
2. Повторное использование реализации.
Применение его для всего остального — misuse. Ты, конечно, можешь думать как угодно, но это то же самое, что раскладывать иконки приложений в Start Menu по цветам.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Override для произвольного метода.
От: Nicht Россия  
Дата: 25.12.08 07:29
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Кстати, в Java все методы по умолчанию виртуальные.


Кстати, это не правда.
private и static методы нифига не виртуальные. Так как они не наследуются.
Да и простые методы обычно хотспотом считаются невиртуальными пока в рантайме не появляются классы которые оверрайдят эти методы. Это дает возможность не парится с виртуальной таблицей до поры до времени из чего следует прирост производительности.
Re[32]: еще один кривой пример
От: Pavel Dvorkin Россия  
Дата: 25.12.08 08:24
Оценка: :)
Только что наткнулся

http://www.rsdn.ru/forum/message/3225099.1.aspx
Автор: muse
Дата: 23.12.08
и ссылки там на codeproject

public class OAKListView : ListView

А ведь C#
With best regards
Pavel Dvorkin
Re[33]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 25.12.08 09:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Нет

Ок, продолжим, мне не сложно..

PD>Ну что же, ясно, впрочем, и изначално ясно было. Я с этим не согласен. Вот и все.

То есть, ты продолжаешь настаивать на том, что раз кто-то сделал криво, значит повторить это не только не зазорно, но и нужно?

PD>Можно ссылку ? Не помню, чтобы мы с тобой это обсуждали. Склероз...

Да пол-топика обсуждений. Наследоваться для расширения функциональности — это криво.

PD>Просто если он кривой, то тогда он такой же аргумент, как и CStringEx

А я его и не использовал в качестве аргумента. Я в принципе не считаю наличие конкретной реализации аргументом в пользу того, что так нужно делать всегда.

PD>-1.

Ну вот, а Саттер, Александреску и Меерс с тобой не согласны..

PD>Слишком уж серьезно это не самое лучшее проявление. Убери класс CStringEx — в общем, никто и не почешется, напишем иной. А вот выкинь это наслелование с полиморфизмом — и не останется в .Net никакого GUI, одни консольные приложения писать будем

Ну, во-первых, я все-таки настаиваю на разделении этих понятий, для пущей корректности. Наследование, лишь один из возможных вариантов реализации ad-hoc полиморфизма, поэтому полиморфизм я бы вообще не трогал. Во-вторых, в данном случае мы обсуждаем исключительно кривость использования наследования для расширения. Этот функционал я бы выкинул с приогромным удовольствием.
Ну и, наконец, в третих, GUI как раз останется, причем существенно лучший чем WinForms, потому что есть WPF, который еще не идеал, конечно, но поддерживает отличнейшие возможности расширения без наследования, чем очень выгодно отличается от WinForms. Собственно, по похожему принципу спроектированы общепризнанно лучшие UI фреймворки (да, я сейчас использую твой аргумент ), явовский swing, напрмер.

PD> Аргумент насчет не лучшего дизайна не приму — почему во всех библиотеках этот не лучший дизайн используется ?

Потому что до лучшего додумались в яве, когда реализовали swing и с тех пор, после того как осознали, что он действительно лучший, вся индустрия планомерно движется в этом направлении, см. WPF. и другие явовские аналоги.

PD>В пределах одной библиотеки ты, надеюсь, не против наследования ?

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

PD> Очевидно, не против, иначе тебе придется всю .Net похоронить.

Павел, я уже много раз тебе говорил — наличие не правильных реализаций, не является аргументом. Никто не утверждает, что библиотека классов .Net задизайнена лучшим из возможных способов, там полно косяков в архитектуре.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.