Re[33]: Override для произвольного метода.
От: LaPerouse  
Дата: 25.12.08 10:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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

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

PD>да и в Яве ИМХО (никогда в яве GUI не писал, так что не уверен). Все они нарушают этот ваш фундаментальный принцип, все используют наследование.


То, что не уверен — хорошо. Так как подобного маразма в java.swing нет. То есть ты конечно вполне можешь отнаследоваться от какого-то JFrame, но это нафиг не нужно (и вредно). Там event-based модель, без всякой виртуальщины. То разница будет между

this.setListener(new Listener...)

и

frame.setListener(new Listener...),

любой более-менее квалифицированный программист выберет второе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[33]: еще один кривой пример
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.08 13:36
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Только что наткнулся

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

PD>public class OAKListView : ListView
PD>А ведь C#

Очередное свидетельство убогости архитектуры WinForms, о чем я буквально недавно писал.
... << RSDN@Home 1.2.0 alpha 4 rev. 1132 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[33]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 25.12.08 20:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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

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

PD> И других тоже.

Что-то никого другого неубежденного пока не видно..

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

Нету за тобой практики, потому что "практика" на которую ты ссылаешься не имеет никакого отношения к делу. Руководствуясь твоей логикой можно прийти к выводу, что нет удобней инструмента для вкалачивания шурупов, чем микроскоп. А что, опыт-то положительный есть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[30]: Override для произвольного метода.
От: Кэр  
Дата: 25.12.08 23:23
Оценка:
Здравствуйте, Sinclair, Вы писали:

LP>>Список — это reverse, concat, replace и т п

LP>>Строка — это IString (to_lower_case, to_upper_case, asBytes)
S>Зачем. ToLower, ToUpper — это всего лишь хелперы для того же IEnumerable<char>:
S>
S>public static IEnumerable<char> String.ToLower(this IEnumerable<char> source)
S>{
S>  foreach(char c in source)
S>      yield return Char.ToLower(c);
S>}
S>

S>Всех делов-то.

Только использовать это нельзя:

For example, There is a ΰ (U+03B0 greek small letter Upsilon with Dialytika and Tonos), however there's no equivilent capital letter. Trying to do ToUpper() ends up returning the same value, although you could perhaps argue for Ϋ́ (U+03AB + U+0301, greeke capital letter upsilon with dialytika, and then a combining tonos) Some other operating systems/environments choose that as the ToUpper() value for U+03B0, so then a single "char" ends up with a 2 "char" upper case form.


А так да — проблема решена...

Думаю, если вводить более удачную абстракцию, чем String — то надо смотреть в сторону IEnumerable<Symbol>, где Symbol может содержать один или два Char. Не факт, что такое решение все еще сможет похвастать хорошим перфомансом. Впрочем можно попробовать.
Re[31]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 03:43
Оценка:
Здравствуйте, Кэр, Вы писали:

Кэр>Только использовать это нельзя:


Кэр>

For example, There is a ? (U+03B0 greek small letter Upsilon with Dialytika and Tonos), however there's no equivilent capital letter. Trying to do ToUpper() ends up returning the same value, although you could perhaps argue for ?? (U+03AB + U+0301, greeke capital letter upsilon with dialytika, and then a combining tonos) Some other operating systems/environments choose that as the ToUpper() value for U+03B0, so then a single "char" ends up with a 2 "char" upper case form.

Кэр>А так да — проблема решена...
На самом деле — ничего страшного.
Просто код хелпера будет чуток посложнее
Кэр>Думаю, если вводить более удачную абстракцию, чем String — то надо смотреть в сторону IEnumerable<Symbol>, где Symbol может содержать один или два Char. Не факт, что такое решение все еще сможет похвастать хорошим перфомансом. Впрочем можно попробовать.
Нужно вводить IEnumerable<CodePoint>. Вот тогда будет почти щасте — с точностью до разных представлений одного и того же глифа при помощи кодепоинтов. "Один или два" — это малоинтересно. Тот char, о котором ты говоришь, это фактически уже UCS-2 encoding. А вовсе не текст.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[32]: Override для произвольного метода.
От: Кэр  
Дата: 26.12.08 04:18
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>На самом деле — ничего страшного.

S>Просто код хелпера будет чуток посложнее

Берем "чуток" в кавычки и я уже согласен Проблемы, которые возможны — для получения перфоманса нам возможно придется затачиваться на конкретную реализацию строки. Тот же IEnumberable очень беден, ни тебе каунта бесплатно, ни доступа по индексу. В частности поэтому мне IEnumerable<char> не очень нравится, как идея.

Кэр>>Думаю, если вводить более удачную абстракцию, чем String — то надо смотреть в сторону IEnumerable<Symbol>, где Symbol может содержать один или два Char. Не факт, что такое решение все еще сможет похвастать хорошим перфомансом. Впрочем можно попробовать.

S>Нужно вводить IEnumerable<CodePoint>. Вот тогда будет почти щасте — с точностью до разных представлений одного и того же глифа при помощи кодепоинтов.
Мне это больше нравится. Но не очень уверен насчет IEnumerable опять же. (Господи, когда же они уже передизайнят коллекции в .Net).

S>"Один или два" — это малоинтересно. Тот char, о котором ты говоришь, это фактически уже UCS-2 encoding. А вовсе не текст.

Вообще-то нет. Один .Net Char — это 16 бит. Таким образом два .Net Char'a могут закодировать все известные на текущий момент Unicode символы (описываются 21-битовым числом).
Re[33]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 04:37
Оценка:
Здравствуйте, Кэр, Вы писали:

Кэр>Берем "чуток" в кавычки и я уже согласен Проблемы, которые возможны — для получения перфоманса нам возможно придется затачиваться на конкретную реализацию строки.

Не, для ToLower — нет. Он же строго локален. Ну то есть для генерации очередного элемента может потребоваться несколько Char, но подряд.
Поэтому никакого особенного индексного доступа не нужно. Будет нормальный конечный автомат, который жует IEnumerable.

Кэр>Тот же IEnumberable очень беден, ни тебе каунта бесплатно, ни доступа по индексу. В частности поэтому мне IEnumerable<char> не очень нравится, как идея.

Вот он мне как раз этим и нравится. Не вполне понятно, с какой целью нужен доступ по произвольному индексу.

Кэр>Вообще-то нет. Один .Net Char — это 16 бит. Таким образом два .Net Char'a могут закодировать все известные на текущий момент Unicode символы (описываются 21-битовым числом).


В Unicode нет "символов". Есть код поинты. И, насколько я помню, в плохих случаях некий глиф может быть представлен то одним код поинтом, то, к примеру, четырьмя. В UCS-2 все эти поинты по-прежнему будут хавать по 16 бит каждый. В основном дело касается combining diacritics.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[34]: Override для произвольного метода.
От: Кэр  
Дата: 26.12.08 05:34
Оценка:
Здравствуйте, Sinclair, Вы писали:

Кэр>>Берем "чуток" в кавычки и я уже согласен Проблемы, которые возможны — для получения перфоманса нам возможно придется затачиваться на конкретную реализацию строки.

S>Не, для ToLower — нет. Он же строго локален. Ну то есть для генерации очередного элемента может потребоваться несколько Char, но подряд.
S>Поэтому никакого особенного индексного доступа не нужно. Будет нормальный конечный автомат, который жует IEnumerable.
Кэр>>Тот же IEnumberable очень беден, ни тебе каунта бесплатно, ни доступа по индексу. В частности поэтому мне IEnumerable<char> не очень нравится, как идея.
S>Вот он мне как раз этим и нравится. Не вполне понятно, с какой целью нужен доступ по произвольному индексу.

Для ToLower возможно. Для каких-нибудь регексов с лупбэками, или всяких алгоритмов поиска подстроки — точно мало.

Кэр>>Вообще-то нет. Один .Net Char — это 16 бит. Таким образом два .Net Char'a могут закодировать все известные на текущий момент Unicode символы (описываются 21-битовым числом).


S> В Unicode нет "символов". Есть код поинты.

Я символы называю код поинтами По моему мы это даже вживую обсуждали

S>И, насколько я помню, в плохих случаях некий глиф может быть представлен то одним код поинтом, то, к примеру, четырьмя. В UCS-2 все эти поинты по-прежнему будут хавать по 16 бит каждый. В основном дело касается combining diacritics.


Насколько я помню, UCS-2 просто делает вид, что не знает про символы (код поинты), для кодировки которых требуются более двух байт.
Re[35]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 06:03
Оценка:
Здравствуйте, Кэр, Вы писали:
Кэр>Для ToLower возможно. Для каких-нибудь регексов с лупбэками, или всяких алгоритмов поиска подстроки — точно мало.
Совершенно не уверен. Я, кстати, потому и написал в самом начале, что не могу сходу придумать IString.
Всякие "алгоритмы поиска подстроки" на самом деле тоже не пользуются индексным доступом — им достаточно кольцевого буфера с размером, зависящим только от размера искомой подстроки.
А вот насчет регекспов я не так уверен. Я в них не очень хорошо разбираюсь. Но есть подозрение, что им хватит поддержки ICloneable<IEnumerator<char>> у результата вызова IString.GetEnumerator()

Кэр>Я символы называю код поинтами По моему мы это даже вживую обсуждали

Так то когда было-то? Я уж не помню подробностей терминологии.
Кэр>Насколько я помню, UCS-2 просто делает вид, что не знает про символы (код поинты), для кодировки которых требуются более двух байт.
Дело, имхо, не в UCS2. Я так понял, что бывают такие сиквенсы кодпоинтов, которые могут вести себя неадекватно по отношению к ToLower/ToUpper. В том смысле, что
а) нельзя процессить их составляющие по отдельности
б) из одного code point на входе может получиться N code points на выходе.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[34]: еще один кривой пример
От: Pavel Dvorkin Россия  
Дата: 26.12.08 06:08
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


А что взамен (для десктопных) ? WPF ?
With best regards
Pavel Dvorkin
Re[36]: Override для произвольного метода.
От: Кэр  
Дата: 26.12.08 06:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

Кэр>>Для ToLower возможно. Для каких-нибудь регексов с лупбэками, или всяких алгоритмов поиска подстроки — точно мало.
S>Совершенно не уверен. Я, кстати, потому и написал в самом начале, что не могу сходу придумать IString.
S>Всякие "алгоритмы поиска подстроки" на самом деле тоже не пользуются индексным доступом — им достаточно кольцевого буфера с размером, зависящим только от размера искомой подстроки.
S>А вот насчет регекспов я не так уверен. Я в них не очень хорошо разбираюсь. Но есть подозрение, что им хватит поддержки ICloneable<IEnumerator<char>> у результата вызова IString.GetEnumerator()

Я так понимаю хаскелевские строки покоя не дают? Ну вообще мне тоже интересно посмотреть, получится ли что-нибудь из подобной идеи.

Кэр>>Я символы называю код поинтами По моему мы это даже вживую обсуждали

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

Кэр>>Насколько я помню, UCS-2 просто делает вид, что не знает про символы (код поинты), для кодировки которых требуются более двух байт.

S>Дело, имхо, не в UCS2. Я так понял, что бывают такие сиквенсы кодпоинтов, которые могут вести себя неадекватно по отношению к ToLower/ToUpper. В том смысле, что
S>а) нельзя процессить их составляющие по отдельности
S>б) из одного code point на входе может получиться N code points на выходе.

Эээ, про UCS-2 у нас речь зашла, когда я предлагал IEnumerable<Symbol>, где Symbol — это один/два .Net Char. Подобная кодировка — это один в один UTF-16, но не UCS-2.

Про ToLower/ToUpper все вроде как верно. Просто опять же там нужно учитывать уйму специфичных случаев вроде немецкой ß, поэтому я и написал, что "чуток" надо взять в кавычки. Код метода должен это как-то учитывать. С другой стороны все эти культурно-зависимые потрошка должны уже в .Net Framework присутствовать. К сожалению .Net тут уходит в native, так что дальше я пока не смотрел.
Re[34]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 26.12.08 06:31
Оценка: :)
Здравствуйте, IB, Вы писали:

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


PD>>Нет

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

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

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

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

Не надо все же демагогии. Ты счтаешь, что этот подход кривой, я — нет. Вот и все.

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

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

Вот тут мы и не сходимся и не сойдемся.

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

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

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

PD>>-1.

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

Ну и бога ради. Я же 100 раз говорил — для меня почти любые "законы" есть не более чем рекомендации, от которых можно и отступить, если есть причины. Иногда лучше сделать хелпер, иногда наследоваться. От ситуации зависит.

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

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

Не удастся. Слишком уж часто он используется. Выкинуть его можно только вместе с почти всеми настольными GUI приложениями и всем ASP.NET. На WINAPI и PHP вернемся ?

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




У WPF масса преимуществ, но только один недостаток — десктопных приложений на нем еще меньше, чем на WinForms, а их там кот наплакал. Судить о пригодности WPF в web-приложениях не берусь, но что касается десктопных — извини.

И потом — как это без наследования? Вот сейчас сделал приложение и что я вижу ?

public partial class Window1 : Window

Window Class
Provides the ability to create, configure, show, and manage the lifetime of windows and dialog boxes.

Если это не наследование, то я китайский император

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

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

. Где эти настольные приложения на swing и WPF ?

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

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

Так тогда просто сказал бы с самого начала, что тебе сама идея наследования кода (не контрактов) вообще не нравится! Я-то полагал, что речь идет о наследовании от чужого класса, а ты, оказывается, против наследования вообще. Это несколько меняет дело.

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

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

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

На этом дискуссию заканчиваю. За тобой право ответа в этой ветке, если хочешь. С Новым Годом!
With best regards
Pavel Dvorkin
Re[35]: еще один кривой пример
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 06:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А что взамен (для десктопных) ? WPF ?

Взамен в каком смысле? В смысле совершенства архитектуры — вот рядом пример привели
Автор: LaPerouse
Дата: 25.12.08
.
В смысле "конкретный фреймворк для UI на винде" — сразу не скажу; скорее всего HTMLayout будет в самый раз. Не факт, что он лучший из возможных.
А вообще практика показывает, что в UI наследование нужно очень-очень редко. Как правило, можно (и лучше) обойтись композицией.
Можно, конечно, и наследованием пользоваться, вот только результат получается хуже.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[34]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 26.12.08 06:39
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


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

G>Если писать будет больше чем один человек, то стоит использовать средства позволяющие писать меньше кода.


Хм... В теории — пожалуй, да. На практике — бог знает. От критериев зависит. Да и количество ошибок не самое главное. Ошибки раньше или позже будут исправлены (не все , а качество кода останется. Что мне за радость, если вместо 1000 строк я могу написать 100 , сделать это практически без ошибок, но в итоге все это будет в 5 раз медленнее работать из-за того, что недостающие 900 строк (а они есть, ты же это понимаешь, их же кто-то написал!) написаны в универсальном виде и поэтому для моей конкретной ситуации дают провал в производительности, например ?
With best regards
Pavel Dvorkin
Re[35]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 07:10
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Хм... В теории — пожалуй, да. На практике — бог знает. От критериев зависит. Да и количество ошибок не самое главное. Ошибки раньше или позже будут исправлены (не все , а качество кода останется. Что мне за радость, если вместо 1000 строк я могу написать 100 , сделать это практически без ошибок, но в итоге все это будет в 5 раз медленнее работать из-за того, что недостающие 900 строк (а они есть, ты же это понимаешь, их же кто-то написал!) написаны в универсальном виде и поэтому для моей конкретной ситуации дают провал в производительности, например ?


Ты очень ловко меняешь тему. Хочешь поговорить о производительности применительно к ОО-дизайну?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[37]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 07:27
Оценка:
Здравствуйте, Кэр, Вы писали:

Кэр>Про ToLower/ToUpper все вроде как верно. Просто опять же там нужно учитывать уйму специфичных случаев вроде немецкой ?, поэтому я и написал, что "чуток" надо взять в кавычки. Код метода должен это как-то учитывать. С другой стороны все эти культурно-зависимые потрошка должны уже в .Net Framework присутствовать. К сожалению .Net тут уходит в native, так что дальше я пока не смотрел.

Ну вот со строками в Нет именно та проблема и есть — что всё в натив. А натив написан в расчете на совершенно специфический layout строк.
И это, наверное, хорошо — в том смысле, что хаскелевские строки потребуют слишком много всего от рантайма.
Ну то есть, в частности, их эффективность сильно зависит от наличия GC, а также от нюансов поведения JIT. Иначе окажется, что в частоиспользуемых частных случаях простые операции привносят неприемлемый оверхед. Грубо говоря, ToUpper в рамках ASCII-7 представления вообще может делаться цепочкой int64-операций, то есть на строках вплоть до 8 символов это вообще один bitwise OR. В каких-то местах это может оказаться важнее, чем выигрышь от O(1)-конактенации.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[34]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 26.12.08 07:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


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

S>Отлично. Этот критерий, конечно же, не так важен — поскольку ускорить прямой код всегда проще, чем выпрямить быстрый



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


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


А можно узнать, почему обязательно если уж наследование, то бездумное ? Я вроде к бездумному не призывал. И потом, если уж ты против бездумного — так с обдуманным наследованием ты согласен ?

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

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

См. мой ответ gandjustas.

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

S>Нет, почему. При прочих равных код, сам написанный "короче и с меньшим...", лучше "хоть святых выноси".

Вот именно что при прочих равных. А они чаще всего совсем не равны.

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


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

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

S>

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


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


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


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


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

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

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


<skipped>

Все, что тебе удалось здесь обосновать — это то, что прочие библиотеки не будут работать с наследником как с наследником, а будут — как с предком. Поэтому тебе и понадобилось сюда передать этот HttpRequest, в котором нет D1String, а есть DString. Я уже на этот вопрос отвечал.

S>Да ну? Во-первых, в наследнике потребуется воспроизвести весь список конструкторов предка — они ведь не наследуются.


С учетом того, что новых параметров здесь нет, это очень-очень сложно


S>Во-вторых, потребуется повторно перегрузить все операторы — они тоже не наследуются.


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


class A {
private :
    int x;
public :
    A(int _x = 0 ) : x(_x) {}
    void operator++()
    {
        x++;
    }

};


class B : public A
{
public :
    B(int _x) : A(_x) {}
};

int _tmain(int argc, _TCHAR* argv[])
{
    B b1(1);
    b1++;
        b1.operator++(); // можно и так, надеюсь, теперь ясно, что это просто функция

    return 0;
}



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


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

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

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

Я так понимаю, что разработчики более поздних Явы и .Net ту же глупость сделали ? String.IndexOf — это не то же самое ?

Или может, глупости ты говоришь ? Как бы мне правильный ответ тут выбрать?

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

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

Ну с самого начала его быть не могло в таком виде по причине отсутствия темплейтов в 1.1

S>Но в реальной жизни мы имеем дело с реальными программистами. Невозможно с первого раза реализовать идеальную библиотеку. Но есть способ дать возможность расширения библиотеки. Эта возможность — есть. Никакого unsealed она не требует.


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


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

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

Именно этого я от тебя и добиваюсь, чтобы ты наконец перестал жестко следовать выученным тобой правилам и понял, что иногда надо от них отступать, а когда это можно делать и когда нельзя — тут как раз голова и требуется.
With best regards
Pavel Dvorkin
Re[35]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.08 08:52
Оценка: +1 -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Не приходилось тебе, видимо, этим заниматься.

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

PD>А можно узнать, почему обязательно если уж наследование, то бездумное ? Я вроде к бездумному не призывал. И потом, если уж ты против бездумного — так с обдуманным наследованием ты согласен ?

Конечно согласен. Можешь перечитать тот самый первый постинг, с которым ты начал спорить.



PD>Все, что тебе удалось здесь обосновать — это то, что прочие библиотеки не будут работать с наследником как с наследником, а будут — как с предком. Поэтому тебе и понадобилось сюда передать этот HttpRequest, в котором нет D1String, а есть DString. Я уже на этот вопрос отвечал.

Плохо отвечал. Некачественно. Тебе до сих пор непонятно, что в твоем подходе для достижения аналогичной производительности придется писать много лишнего кода? Ок, я тебе больше отвечать не буду, пока ты не приведешь полный компилирующийся пример, иллюстрирующий твой подход.
PD> С учетом того, что новых параметров здесь нет, это очень-очень сложно
А ты код в студию приведи.
PD>Слушай, ты хоть по языку руководство почитал бы, что ли... . С чего это им всем не наследоваться-то, если это просто функции со специфическим именем ?
Ай, молодца. А теперь покажи такой же трюк для не-void оператора? Покажи-ка мне хоть один void оператор в классе CString!
На всякий случай напомню глубоким знатокам языка, что в CString есть 8 конструкторов, 8 операторов и 5 функций, которые возвращают CString. В твоем CPavelDvorkinIdioticStringWithIsPalindrome тебе придется перегрузить их все.

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

То есть по делу сказать нечего.

PD>Я так понимаю, что разработчики более поздних Явы и .Net ту же глупость сделали ? String.IndexOf — это не то же самое ?

Да, это тоже плохое решение. Я об этом писал в параллельной ветке.

PD>Ну с самого начала его быть не могло в таком виде по причине отсутствия темплейтов в 1.1

Правильно.

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

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

Примеры, которые ты приводишь, не выдерживают никакой критики. Вот ты утверждаешь, что наследование даст возможность получить "один самый лучший класс". Ну, и где он? Я беглым просмотром нашел не то три, не то четыре разных реализации CStringEx. Что-то не видно, чтобы их авторы отреагировали на твои мечты и добавили функции друг в друга.
Не работает модель. А в случае хелперов прикладному программисту не нужно выбирать ровно один класс из кучи малопригодных инвалидов. Он может совместно использовать хелперы.
В принципе, понятно, что ты мало знаком с реалиями промышленной разработки софта. Но вот то, что ты не хочешь прислушаться к тем, кто знаком — вот это уже непонятно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[35]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 26.12.08 09:34
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD> Так что предоставляю тебе возможность ответить, если хочешь, но я уже отвечать не буду больше.

Как жаль, что мы так и не услышали начальника транспортного цеха... Аргументов у тебя так и не нашлось..

PD>В общем, все и так ясно.

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

PD>Не надо все же демагогии. Ты счтаешь, что этот подход кривой, я — нет. Вот и все.

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

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

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

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

Ну так назови причину, Павел! Ну хоть одну!! =) Что, нету? Ну я так и думал..

PD>Не удастся.

Ну почему, мне как-то удается.

PD> Слишком уж часто он используется.

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

PD> Выкинуть его можно только вместе с почти всеми настольными GUI приложениями и всем ASP.NET. На WINAPI и PHP вернемся ?

ASP.Net отлично без этого обходится, в настольных тоже есть альтернативы, так что, не стоит лезть в незнакомую область с шашкой на голо..

PD>У WPF масса преимуществ, но только один недостаток — десктопных приложений на нем еще меньше, чем на WinForms, а их там кот наплакал. Судить о пригодности WPF в web-приложениях не берусь, но что касается десктопных — извини.

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

PD>И потом — как это без наследования?

Вопервых, не говорил, что WPF обошелся вообще без наследования, а во-вторых, ты забываешь про полиморфизм.

PD>. Где эти настольные приложения на swing и WPF ?

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

PD>Это несколько меняет дело.

В данной дискуссии, ничего не меняет.

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

С чего ты взял, что они практически не применимые. Практически, они применимые намного лучше тех решений, которые отстаиваешь ты.

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

Так оглянись, Павел, достань уже голову из MFC. Добро пожаловать в реальный мир..
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[36]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 29.12.08 02:35
Оценка: -3 :))
Здравствуйте, Sinclair, Вы писали:

PD>>Слушай, ты хоть по языку руководство почитал бы, что ли... . С чего это им всем не наследоваться-то, если это просто функции со специфическим именем ?

S> Ай, молодца. А теперь покажи такой же трюк для не-void оператора?

Это ты трюком называешь ? Ну-ну... Это самая обычная реализация.

Насчет не void — please



#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
#include "malloc.h"

class A {
private :
    char* m_str;
public:

    operator int()
    {
        return atoi(m_str); // error handling skipped
    }
    operator char*()
    {
        return m_str;
    }
    A(char* p = NULL)
    {
        m_str = strdup(p);
    }
    virtual ~A()
    {
        free(m_str);
    }
};

class B :public A
{
public :
    B(char* p = NULL) : A(p) {}
};

int _tmain(int argc, _TCHAR* argv[])
{
    B b("123");
    int i = b;
    return 0;
}




>Покажи-ка мне хоть один void оператор в классе CString!


Учи язык прежде чем что-то заявлять!!



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


Да, плохо твое дело, если уж не остается ничего, кроме оскорблений. Впрочем, я тебя понимаю. Такой великий специалист и так глупо прокололся


PD>>Я так понимаю, что разработчики более поздних Явы и .Net ту же глупость сделали ? String.IndexOf — это не то же самое ?

S>Да, это тоже плохое решение. Я об этом писал в параллельной ветке.

Как хорошо, что авторы MFC, Java и C# ее не читали


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

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

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

S>В принципе, понятно, что ты мало знаком с реалиями промышленной разработки софта.


С Вашими реалиями я , может, и не очень знаком, да и не нужны они мне. У меня своих реалий хватит, ну а насчет промышленного
With best regards
Pavel Dvorkin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.