Re[15]: Override для произвольного метода.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.12.08 07:55
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


G>>>>Или вы предлагаете весь .NET переписать на использование MyString?

PD>>>Нет, зачем же. Наследовать там, где надо.
G>>То есть переписать пол фреймворка. Удачи.
PD>Что за чепуха ? Мне это нужно для своих целей, допустим. Я в тех классах, что перепишу, буду использовать этот свой MyString. Зачем фреймворку IsPalindrom ? Он мне нужен, а не ему.
Тогда что вы пытаетесь доказать? Создавайте IsPalindrom который будете использовать.

G>>Так создавайте свой фреймворк, кто же вам мешает?

PD>Пошла уже демагогия. Я хочу расширить его для своих целей и на это я имею право. Создавать новый оснований требовать у вас нет.
Кого расширить?

PD>>>Это раз. А во-вторых, кроме этих 2 есть и третья причина — расширение возможностей класса.

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

G>>Для вашего класса MyString вам придется написать библиотеку, которая понимает MyString. А если подумать то оказывается в таком случае необязательно наследоваться от String, чтобы получить туже функциональность, можно воспользоваться агрегацией.

PD>Агрегация — это как ? Написать свой класс, в нем в качестве поля string и экспонировать все его методы ? Спасибо. Во-первых, мне что, время не на что тратить ? А во-вторых, какая тут логика будет ? Чтобы строку проверять на палиндром, надо, оказывается, ее в другой класс засунуть . Появится желание еще что-то сделать — еще один класс и в нем тоже все экспонировать ? А если кто-то захочет мой класс расширить — он его тоже должен агрегировать и все экспонировать ? Так сказать, двойная агрегация. То-то весело будет...
Ко всему надо подходить с умом, а не так как вы.
Re[15]: Override для произвольного метода.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.12.08 08:03
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

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


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

G>>Это не ошибка а правда жизни. Наследование радо добавления методов — ерунда. Это было модно 10-15 лет назад, сейчас пришло просветление в головы теоретиков ООП.

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

G>>Это действительно ерунда.

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

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

PD>Ну когда аргументы на таком уровне приводят (см. выделенное), то дискутировать дальше нет смысла.


Да что аргументов и не видно было. Все на уровне "мне так хочется".
Re[13]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.08 08:18
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Я просто имел в виду, что все методы в Яве виртуальные.

Я просто имел в виду, что это неправда.

PD>Перечитал. Те, кто используют обычный string — да, должны. Те, кто будут использовать MyString — не должны. Вот напишу свою PalindroManager и в нем будет исключительно MyString использоваться.

Павел, ты правда не понимаешь, или придуряешься?
Твоим MyString не пользуется никто. Текстбоксы не возвращают MyString. TextReader не читает MyString из стрима. StringBuilder не собирает MyString. Нет ни одного метода во всем огромном множестве кода, который бы вернул тебе MyString.
Твоя библиотека или приложение не будет работать в вакууме. Придется как-то интероперировать с окружающим миром. И ты на полном серъезе предлагаешь только ради проверки на палиндромность порождать новый класс, который потребует предварительной конверсии каждой строки для выполнения проверки?


Какая идея может оправдать этот немыслимый бред? По-моему, никакая.

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

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

PD>Нет.

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

PD>Понят, понят. См. выше.

Нет, не понят. Ты попробуй все же придумать, хотя бы в уме, реалистичный пример реализации хотя бы того же PalindroManager. Я тебе заранее говорю: как бы ты ни подгонял задачу под свое решение, extension method будет комфортнее в использовании. С ним PalinroManager будет короче и понятнее.

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

Ничего подобного. Я просто пытаюсь тебе показать, что все вопросы правильно/неправильно решаются исключительно сравнением кода. Если для использующего кода нет никакой разницы, что там написано, то нет смысла и настаивать на своем. Получается, что ты жалуешься на несуществующее ограничение. Задача, которую ты поставил — написать класс с другими методами итерирования по каталогу — решается на существуюшем языке, и невозможность наследования от класса Directory никак этому не мешает.

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

А теперь ты лихорадочно пытаешься придумать еще хоть какие-то аргументы в защиту своего заблуждения. Ок, какая именно логичность появляется от того, что MyDirectory отнаследован от Directory.

PD>Вот ответь на вопрос — а зачем в C# вообще static классы ? Инстансов от них не дождешься, это просто набор методов. Почему бы просто внеклассовые функции не разрешить, как в С++ ? Упаковать их в namespace и дело с концом, туда никто не запрещает добавлять. Так нет же, все же в класс их поместили. И правильно.

И какое отношение этот вопрос имеет к разрешению наслледоваться от класса Directory?


PD>Так все же был бы один класс! Тогда ответь на вопрос — а почему ? Иными словами, какие идейные соображения движут тобой, когда ты принимаешь решение — быть тут одному классу или нескольким ? Подчеркиваю, речь идет о static классах, так чтт без виртуальных рассуждений, please.

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


PD>Да и вообще модификации — это и замена, и добавление. А замена, в свою очередь — замена виртуальных и невиртуальных. А добавление — инстансных или статических. ИМХО вместо того, чтобы чохом запрещать все, надо было более гибкую политику вести. Например, запретить переопределение виртуальных методов базового класса, но разрешить добавление новых методов.

Это делается путем запечатывания отдельных методов.
PD>И т.д. Возможно, следовало бы вместо sealed аттрибуты использовать или играть с модификаторами доступа.
Рекомендую сначала ознакомиться с матчастью. После этого внятно сформулировать свои претензии к ней. Желательно в виде примеров. Пока что оба примера не выдерживают никакой критики: в одном случае использование наследования не играет никакой роли, в другом приводит к ухудшению свойств решения.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 10.12.08 08:44
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Да что аргументов и не видно было. Все на уровне "мне так хочется".


Я имею в виду качество твоих аргументов — см. выделенное в прошлом письме
With best regards
Pavel Dvorkin
Re[16]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 10.12.08 08:51
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Тогда что вы пытаетесь доказать? Создавайте IsPalindrom который будете использовать.


Не могу — класс String sealed.

G>>>Так создавайте свой фреймворк, кто же вам мешает?

PD>>Пошла уже демагогия. Я хочу расширить его для своих целей и на это я имею право. Создавать новый оснований требовать у вас нет.
G>Кого расширить?

Фреймворк.

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


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

class MyString : String
class MyFrameWork : FrameWork

в классе FrameWork никто про MyString не знает, верно. А в классе MyFrameWork знают и используют. И для этого мне не надо переписать весь FrameWork, хватит переписывания нескольких методов. Все остальное возьмем от FrameWork, в котором никто про MyString не знает — и не надо.

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


Не создавать, а расширять существующий — см. выше.

PD>>Агрегация — это как ? Написать свой класс, в нем в качестве поля string и экспонировать все его методы ? Спасибо. Во-первых, мне что, время не на что тратить ? А во-вторых, какая тут логика будет ? Чтобы строку проверять на палиндром, надо, оказывается, ее в другой класс засунуть . Появится желание еще что-то сделать — еще один класс и в нем тоже все экспонировать ? А если кто-то захочет мой класс расширить — он его тоже должен агрегировать и все экспонировать ? Так сказать, двойная агрегация. То-то весело будет...

G>Ко всему надо подходить с умом, а не так как вы.

А можно продемонстрировать подход с умом с агрегацией в примере IsPalindrom ? Мне просто интересно, как это в данном случае агрегировать с умом
With best regards
Pavel Dvorkin
Re[14]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 10.12.08 10:07
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


PD>>Я просто имел в виду, что все методы в Яве виртуальные.

S>Я просто имел в виду, что это неправда.

PD>>Перечитал. Те, кто используют обычный string — да, должны. Те, кто будут использовать MyString — не должны. Вот напишу свою PalindroManager и в нем будет исключительно MyString использоваться.

S>Павел, ты правда не понимаешь, или придуряешься?
S>Твоим MyString не пользуется никто. Текстбоксы не возвращают MyString. TextReader не читает MyString из стрима. StringBuilder не собирает MyString. Нет ни одного метода во всем огромном множестве кода, который бы вернул тебе MyString.

Слушай, не придуривайся сам. Из того, что в существующем FW никто с ним работать иначе как со string не будет (еще бы!) вовсе не следует, что в расширении FW его нельзя будет использовать.

S>Твоя библиотека или приложение не будет работать в вакууме. Придется как-то интероперировать с окружающим миром. И ты на полном серъезе предлагаешь только ради проверки на палиндромность порождать новый класс, который потребует предварительной конверсии каждой строки для выполнения проверки?


Какой к богу проверки ? Создаем наследника от TextBox, к примеру. Кладем его на форму. В нем поле MyString Text1. В него считываем из Win32 edit, создавая при этом экземпляр MyString. Проверяем его на палиндром — здесь же, в наследнике TextBox. Все. Во всем остальном он ведет себя как обычный String и в таком виде может быть употреблен где угодно в существующем FW, которому совсем не надо знать, что он MyString. Никакая дополнительная виртуальность здесь не нужна.

S>Какая идея может оправдать этот немыслимый бред? По-моему, никакая.


Что у вас за дурная манера , господа, называть все, с чем вы не согласны, бредом ?

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

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

Обоснуй насчет производительности программы на примере моего расширения MyString и твоей Utility. Имей в виду — функция не виртуальная, так что насчет callvirt — не надо.



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

S>А теперь ты лихорадочно пытаешься придумать еще хоть какие-то аргументы в защиту своего заблуждения. Ок, какая именно логичность появляется от того, что MyDirectory отнаследован от Directory.

А какая логичность в том, что в классе MyDirectory обраны эти методы, а не создано 3 класса, по которым их бы разнесли ? Логичность в том, что класс их объединяет в нечто логически целое — в данном случае (static class) вот и все.

PD>>Вот ответь на вопрос — а зачем в C# вообще static классы ? Инстансов от них не дождешься, это просто набор методов. Почему бы просто внеклассовые функции не разрешить, как в С++ ? Упаковать их в namespace и дело с концом, туда никто не запрещает добавлять. Так нет же, все же в класс их поместили. И правильно.

S>И какое отношение этот вопрос имеет к разрешению наслледоваться от класса Directory?

Самое прямое. Если я расширяю класс Directory — я создаю более мощный "Directory". То есть static класс есть логически собранный набор методов для определенной области. Средство организации, так сказать. И поэтому все средства для работы с этой областью должны быть в этом классе, а не где угодно еще. Или в расширенном классе.
Если ты с этим не согласен — тогда зачем вообще этот класс ? Разместить их по namespace и дело с концом. Зачем класс нужен ?


PD>>Так все же был бы один класс! Тогда ответь на вопрос — а почему ? Иными словами, какие идейные соображения движут тобой, когда ты принимаешь решение — быть тут одному классу или нескольким ? Подчеркиваю, речь идет о static классах, так чтт без виртуальных рассуждений, please.

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

Уход от ответа из-за его отсутствия. А если бы ты реально при изготовлении этого класса с нуля разбил его без всякого смысла и логики на 2 — сочувствую...

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


Слова, слова...

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


Если ты не понимаешь разницу между введением еще одного класса, не имеющего никакого отношения к данному и созданием наследника, расширяющего возможности данного и лишь подсчитываешь число классов — о чем тогда вообще говорить!

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

Ладно, все, хватит.
With best regards
Pavel Dvorkin
Re[15]: Override для произвольного метода.
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.12.08 10:16
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Какой к богу проверки ? Создаем наследника от TextBox, к примеру. Кладем его на форму. В нем поле MyString Text1. В него считываем из Win32 edit, создавая при этом экземпляр MyString. Проверяем его на палиндром — здесь же, в наследнике TextBox. Все. Во всем остальном он ведет себя как обычный String и в таком виде может быть употреблен где угодно в существующем FW, которому совсем не надо знать, что он MyString. Никакая дополнительная виртуальность здесь не нужна.


Выделенное нужно только для того, чтобы обратиться к методу IsPalindrome? Не проще ли передать строку в статический метод Utils.IsPalindrome(string)? Или воспользоваться Extension методом?
Re[17]: Override для произвольного метода.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.12.08 10:30
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


G>>Тогда что вы пытаетесь доказать? Создавайте IsPalindrom который будете использовать.

PD>Не могу — класс String sealed.
Создайте Extension метод, зачем вам наследование?
В любом случае придется писать новый класс, у String нету виртуальных методов, чтобы их можно было переопределить.
И вообще наследоваться от String — плохая идея, синклер уже объяснил.

G>>>>Так создавайте свой фреймворк, кто же вам мешает?

PD>>>Пошла уже демагогия. Я хочу расширить его для своих целей и на это я имею право. Создавать новый оснований требовать у вас нет.
G>>Кого расширить?
PD>Фреймворк.
Конкретнее, какие именно классы зачем расширить?
Про String и Directory уже объяснили что это не нужно или неправильно. Остальное — только ваши желания, имеющие мало общего с реальностью.

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

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

PD>class MyString : String

PD>class MyFrameWork : FrameWork

PD>в классе FrameWork никто про MyString не знает, верно. А в классе MyFrameWork знают и используют. И для этого мне не надо переписать весь FrameWork, хватит переписывания нескольких методов. Все остальное возьмем от FrameWork, в котором никто про MyString не знает — и не надо.

Нескольких, это скольких? В реальном проекте окажется огромное количество.
Даже переписывания одного метода фреймворка уже слишком много для того чтобы добавить один, нафиг никому не нужный, метод в класс String.

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

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

Если же у вас MyString используется в одном месте, то вам и классы не нужны, достаточно написать код из MyString по месту использования.

PD>>>Агрегация — это как ? Написать свой класс, в нем в качестве поля string и экспонировать все его методы ? Спасибо. Во-первых, мне что, время не на что тратить ? А во-вторых, какая тут логика будет ? Чтобы строку проверять на палиндром, надо, оказывается, ее в другой класс засунуть . Появится желание еще что-то сделать — еще один класс и в нем тоже все экспонировать ? А если кто-то захочет мой класс расширить — он его тоже должен агрегировать и все экспонировать ? Так сказать, двойная агрегация. То-то весело будет...

G>>Ко всему надо подходить с умом, а не так как вы.

PD>А можно продемонстрировать подход с умом с агрегацией в примере IsPalindrom ? Мне просто интересно, как это в данном случае агрегировать с умом


Ничего агрегировать не надо, достаточно содзать extension
Re[17]: Override для произвольного метода.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.12.08 10:31
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


G>>Да что аргументов и не видно было. Все на уровне "мне так хочется".

PD>Я имею в виду качество твоих аргументов — см. выделенное в прошлом письме

Это не агрументы, а оценка твоих слов.
Re[15]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.08 11:17
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Слушай, не придуривайся сам. Из того, что в существующем FW никто с ним работать иначе как со string не будет (еще бы!) вовсе не следует, что в расширении FW его нельзя будет использовать.

Павел, я в четвертый раз настаиваю на том, что даже "в расширении FW" с твоей строкой будет работать менее удобно, чем с внешним методом IsPalindrome.
S
PD>Какой к богу проверки ? Создаем наследника от TextBox, к примеру.
Отлично. То есть нам уже нужно создавать наследника от TextBox. Спрашивается — нахрена? Это что, более удобно, чем пользоваться стандартным TextBox?
А если строку надо читать из файла, то будем наследоваться от TextReader?

PD>Кладем его на форму. В нем поле MyString Text1. В него считываем из Win32 edit, создавая при этом экземпляр MyString.

Отлично. То есть вместо использования существующей строки, мы создаем ее дубликат. Точнее, в данном контексте уже предлагается отказаться от готовой инфраструктуры WinForms, и напрямую бегать в Win32 через интероп. И всё это ради того, чтобы узнать, не является ли введенная пользователем строка палиндромом?

S>>Какая идея может оправдать этот немыслимый бред? По-моему, никакая.

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

PD>Обоснуй насчет производительности программы на примере моего расширения MyString и твоей Utility. Имей в виду — функция не виртуальная, так что насчет callvirt — не надо.

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


PD>А какая логичность в том, что в классе MyDirectory обраны эти методы, а не создано 3 класса, по которым их бы разнесли ?

Какие методы? Твои три метода вместо одного, который возвращает IEnumerable? Никакой логичности, очевидно, нет. Глядя на код я сразу вижу, что его писал человек, не знакомый с .Net Framework.

S>>И какое отношение этот вопрос имеет к разрешению наслледоваться от класса Directory?

PD>Самое прямое. Если я расширяю класс Directory — я создаю более мощный "Directory". То есть static класс есть логически собранный набор методов для определенной области. Средство организации, так сказать. И поэтому все средства для работы с этой областью должны быть в этом классе, а не где угодно еще. Или в расширенном классе.
Ну они и так в расширенном классе. По прежнему жду примера кода, который пользуется твоим MyDirectory, и при этом ты не можешь написать этот MyDirectory на существующем C#.

PD>Если ты с этим не согласен — тогда зачем вообще этот класс ? Разместить их по namespace и дело с концом. Зачем класс нужен ?

Я потерял нить рассуждений.

PD>Если ты не понимаешь разницу между введением еще одного класса, не имеющего никакого отношения к данному и созданием наследника, расширяющего возможности данного и лишь подсчитываешь число классов — о чем тогда вообще говорить!

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

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

Ничего плохого, очевидно, не будет. Скорее наоборот — будет набор ортогональных утилитных классов. Ими можно будет пользоваться достаточно удобным способом.
А ты лучше на досуге подумай, как будет выглядеть аналог с наследованием. От кого я буду наследовать MyDirectory — от Directory или от YourDirectory? Почему? Как быть, если мы не знали о библиотеках друг друга во время разработки?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 10.12.08 11:47
Оценка: +7 -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Слушай, не придуривайся сам. Из того, что в существующем FW никто с ним работать иначе как со string не будет (еще бы!) вовсе не следует, что в расширении FW его нельзя будет использовать.

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

PD>Какой к богу проверки ? Создаем наследника от TextBox, к примеру. Кладем его на форму. В нем поле MyString Text1. В него считываем из Win32 edit, создавая при этом экземпляр MyString. Проверяем его на палиндром — здесь же, в наследнике TextBox. Все.

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

PD>Что у вас за дурная манера , господа, называть все, с чем вы не согласны, бредом ?

Мы с этим не просто не согласны, мы знаем, что так делать нельзя и даже пытаемся тебе объяснить почему, но очевидно бесполезно... =)

PD> Логичность в том, что класс их объединяет в нечто логически целое — в данном случае (static class) вот и все.

Объеденить в "логически целое" можно кучей других способов, почему они тебя не устраивают?

PD>Самое прямое. Если я расширяю класс Directory — я создаю более мощный "Directory". То есть static класс есть логически собранный набор методов для определенной области.

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

PD>Слова, слова...

Это не слова, это суровая практика. Вот что по этому поводу пишет Меерс:

...
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.


PD>Если ты не понимаешь разницу между введением еще одного класса, не имеющего никакого отношения к данному и созданием наследника, расширяющего возможности данного и лишь подсчитываешь число классов — о чем тогда вообще говорить!

Мы-то как раз очень хорошо понимаем разницу и все ее последствия.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[13]: Override для произвольного метода.
От: EvilChild Ниоткуда  
Дата: 10.12.08 16:52
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>>>А он почти как синглетон — антипатерн. Но не такой разрушительной силы слава богу.


EC>>А можно раскрыть мысль?


GIV>Его недостатки происходят из-за того что в нем надо наследоваться от абстрактного класса.

Строго говоря класс не обязан быть абстрактным.

GIV>Соответственно связанность сильно увеличивается, добавление второго и последующих template method в иерархию ничем хорошим не кончается. Да и с одним не все так гладко (см. Call super антипатерн).


Как-то странно для меня звучит упрёк в адрес наследования, при обсуждении техники примененимой только в рамках наследования.
Или я трактую паттерн слишком узко?
now playing: Oliver Koletzki — Requiem Für Die Vernunft (Lützenkirchen Remix)
Re[14]: Override для произвольного метода.
От: GarryIV  
Дата: 10.12.08 20:26
Оценка:
Здравствуйте, EvilChild, Вы писали:

GIV>>>>А он почти как синглетон — антипатерн. Но не такой разрушительной силы слава богу.


EC>>>А можно раскрыть мысль?


GIV>>Его недостатки происходят из-за того что в нем надо наследоваться от абстрактного класса.

EC>Строго говоря класс не обязан быть абстрактным.

Шаблонный метод == абстрактный метод => класс абстрактный.

GIV>>Соответственно связанность сильно увеличивается, добавление второго и последующих template method в иерархию ничем хорошим не кончается. Да и с одним не все так гладко (см. Call super антипатерн).


EC>Как-то странно для меня звучит упрёк в адрес наследования, при обсуждении техники примененимой только в рамках наследования.

EC>Или я трактую паттерн слишком узко?

Ну я и говорю, наследование реализации вообще стремная штука а template method в частности
WBR, Igor Evgrafov
Re[15]: Override для произвольного метода.
От: EvilChild Ниоткуда  
Дата: 10.12.08 20:56
Оценка: +1
Здравствуйте, GarryIV, Вы писали:

GIV>Шаблонный метод == абстрактный метод => класс абстрактный.

Т.е. виртуальная функция с реализацией уже не канает?
now playing: Oliver Koletzki — Requiem Für Die Vernunft (Lützenkirchen Dub Edit)
Re[16]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 11.12.08 06:04
Оценка:
Здравствуйте, IB, Вы писали:

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

IB>Примерно так проектируют приложение люди познакомившиеся с основами ООП по книжкам, примерно месяц назад и теперь активно спешащие применить все новые фенечки на практике..

Неужели трудно понять , что этот пример просто-напросто придуман за 2 минуты, чтобы продемонстрировать суть того, о чем я говорю. А суть проста — мы можем породить некий новый класс A1 от существующего класса A, и некий новый класс B1 от существующего класса B. Внутри класса A1 будет использоваться класс B1, в то время как в классе A экземпляры B1 будут выглядеть как B. При этом не возникает необходимости в полиморфизме-виртуальности. Примеров таких на свете сколько угодно.

Вот, например класс CStringEx — расширяет стандартный класс CString из MFC

http://www.codeguru.com/cpp/cpp/string/ext/article.php/c2793

/////////////////////////////////////////////////////////////////
The constructors in the CStringEx class parallel the constructor in CString and in fact simply chains into the corresponding CString constructor. Some of the CStringEx functions use knowledge of the internal structure of the CString object so there is a small chance that these functions might break if the CString implementation changes.

The functions provided by CStringEx are quite easy to use and fairly simple to understand. The Insert() functions inserts a character or a sub-string within a string. The result is similar to inserting text in an edit control, the string is expanded to accommodate the sub-string. The Delete() function removes a segment from the string and shortens it. The Replace() function removes a sub-string and replaces it with another. Again, the string size is adjusted depending on the size of the sub-string that was removed and the size of the sub-string that was inserted.

The find family of functions, finds a sub-string in the forward or the reverse direction. The NoCase version of these functions are case insensitive. The FindReplace() and FindReplaceNoCase() functions searches for a sub-string and replaces the matching sub-string with another string. The GetField() and GetDelimitedField() functions find a token in the string. The table below exemplifies the uses of these functions.
/////////////////////////////////////////////////////////////////

Естественно, внутри каркаса MFC экземпляры CStringEx выглядят как CString. Но в нем есть дополнительные средства, которые удобны.




PD>>Что у вас за дурная манера , господа, называть все, с чем вы не согласны, бредом ?

IB>Мы с этим не просто не согласны, мы знаем, что так делать нельзя и даже пытаемся тебе объяснить почему, но очевидно бесполезно... =)

Ну тогда объясни это же тем, кто написал этот класс и кто его использует.
With best regards
Pavel Dvorkin
Re[16]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 11.12.08 06:21
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Отлично. То есть вместо использования существующей строки, мы создаем ее дубликат. Точнее, в данном контексте уже предлагается отказаться от готовой инфраструктуры WinForms, и напрямую бегать в Win32 через интероп. И всё это ради того, чтобы узнать, не является ли введенная пользователем строка палиндромом?


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

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

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

Да уж. Каждый начнет свой класс делать. Насчет ортогональности — это ты прав. Только вот методы не ортогональны будут. Потому что каждый будет свой набор делать, и они безусловно в чем-то будут совпадать.

S>А ты лучше на досуге подумай, как будет выглядеть аналог с наследованием. От кого я буду наследовать MyDirectory — от Directory или от YourDirectory? Почему? Как быть, если мы не знали о библиотеках друг друга во время разработки?


Вообще-то этот вопрос рассматривается во всех курсах по ООП — от какого базового класса надо производить наследование и в каком случае.
With best regards
Pavel Dvorkin
Re[17]: Override для произвольного метода.
От: Klapaucius  
Дата: 11.12.08 08:03
Оценка: +2 -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Неужели трудно понять , что этот пример просто-напросто придуман за 2 минуты, чтобы продемонстрировать суть того, о чем я говорю.


Не лучше ли было потратить 4 минуты и придумать пример получше?

PD>А суть проста — мы можем породить некий новый класс A1 от существующего класса A, и некий новый класс B1 от существующего класса B. Внутри класса A1 будет использоваться класс B1, в то время как в классе A экземпляры B1 будут выглядеть как B. При этом не возникает необходимости в полиморфизме-виртуальности. Примеров таких на свете сколько угодно.


Да все понятно.

Метод-расширение.

или

Класс A' наследник класса A. И N классов B'i, наследников классов Bi.

Это даже не геморрой. Это рак.

Разработчики библиотек прищемляют нашу свободу. Мешают пойти по второму пути. Запечатывают классы. Негодяи!
... << RSDN@Home 1.2.0 alpha 4 rev. 1110>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[17]: Override для произвольного метода.
От: 4058  
Дата: 11.12.08 10:06
Оценка: 7 (2) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Вот, например класс CStringEx — расширяет стандартный класс CString из MFC


1. System.String в отличие от CString иммутабелен, в частности по этому класс запечатан.

Пример:


class PDString : String
{
    bool MySuperFunc();    
}


PDString pds ...;
... pds.Replace('asdas', 'asdasd')

— вуалья, возвращается System.String.
Я думаю дальше не имеет смысла описывать суть проблемы, наследования от иммутабельных классов.

2. Переопределенные операторы не наследуются (как минимум прийдется переопределить операторы конкатенации).

3. В вашем случае задача не решается агрегацией (т.к. (1) и как вы правильно заметили прийдется педалить весь интерфейс System.String), а решается предположенным вам сервисным классом, который предоставляет необходимую функциональность. В данном случае это самый лучший вариант.

P.S. Наследование с целью расширения функциональности достаточно распространенная ошибка, об этом еще давно Страуструп упонинал в своей немногочисленной литературе.
мой первый супер string
Re[17]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 11.12.08 11:18
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Неужели трудно понять , что этот пример просто-напросто придуман за 2 минуты, чтобы продемонстрировать суть того, о чем я говорю.

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

PD>А суть проста — мы можем породить некий новый класс A1 от существующего класса A, и некий новый класс B1 от существующего класса B. Внутри класса A1 будет использоваться класс B1, в то время как в классе A экземпляры B1 будут выглядеть как B.

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

PD> Примеров таких на свете сколько угодно.

Ну давай, практический пример, где бы это было оправдано, хоть один?

PD>Вот, например класс CStringEx — расширяет стандартный класс CString из MFC

Если в одном месте накосячили, значит везде нужно? Тут ребята наступили ровно на те же грабли, более того, они это явно осознают:
Some of the CStringEx functions use knowledge of the internal structure of the CString object so there is a small chance that these functions might break if the CString implementation changes.
Это настолько явный косяк, что тут даже говорить не о чем. И вообще, с каких пор кривые реализации левых библиотек стали аргументом?
Эти ребята, всего лишь, в очередной раз показали как нельзя делать.

PD>Естественно, внутри каркаса MFC экземпляры CStringEx выглядят как CString. Но в нем есть дополнительные средства, которые удобны.

Тебе Антон уже на пальцах показал, все последствия этой кажимой удобности.

PD>Ну тогда объясни это же тем, кто написал этот класс и кто его использует.

Вот я тебе и объясняю, что это не просто криво, а является грубейшей ошибкой в следствии не понимания того, что собственно представляет собой ООП и как им правильно пользоваться.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[18]: Override для произвольного метода.
От: LaPerouse  
Дата: 11.12.08 14:18
Оценка:
Здравствуйте, IB, Вы писали:

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


PD>> Примеров таких на свете сколько угодно.

IB>Ну давай, практический пример, где бы это было оправдано, хоть один?

Почему же, можно придумать такие примеры.

Собственно, какие преимущества могут быть у создания наследника с нужным методом по сравнению с тем случаем, когда этот метод — внешний (в делегирующем классе или вовсе статич.)? Только одно — полиморфное использование соотв. класса через библиотечный интерфейс — в данном случае String. Чтобы с новым объектом MyString можно было работать как со String. И чтобы библ. методы могли таким образом использовать эту реализацию. Если бы String создавался только через фабрику и мы бы имели бы возможность сделать String.setCurrentFactoty(myStringFactory), то такое очень даже имело бы смысл. Другое дело, что в этом случае автор библиотеки вряд ли стал бы закрывать String... Так как он был бы расчитан на такое вот применение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.