Re[23]: Override для произвольного метода.
От: Cyberax Марс  
Дата: 15.12.08 02:17
Оценка: +4
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Все, дальше не стоит обсуждать.

PD>И все эти люди , в том числе уважаемый SchweinDeBurg, который регулярно выдает [ANN} по этому сайту, используют индуссские поделки ради строчки и т.д.
На Codeproject таки, действительно, полно поделок. Их там как раз большая часть и есть.
Sapienti sat!
Re[22]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 15.12.08 02:19
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Гы гы.


Исключительной силы аргумент!

http://www.rsdn.ru/forum/message/3214195.1.aspx
Автор: Pavel Dvorkin
Дата: 15.12.08
With best regards
Pavel Dvorkin
Re[22]: offtop
От: Pavel Dvorkin Россия  
Дата: 15.12.08 02:22
Оценка:
Здравствуйте, 4058, Вы писали:

4>Практика бывает плохая и хорошая, собственно как и теория, и MFC приводить в качестве примера хорошей практики очень сомнительно.


MFC, конечно, устарела по концепциям, но по качеству кода (в рамках своих концепций) — она на порядок лучше. Во всяком случае, такого безобразия, как пересоздания listview с переливанием данных ради того, чтобы установить флаг сортировки, там не найдешь.
With best regards
Pavel Dvorkin
Re[22]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 15.12.08 02:54
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>А зачем наследование от библиотечного класса без полиморфизма? Назови, пожалуйста, хоть одно преимущества. Недостатки очевидны:

LP>1. Пользуясь protected-методами в наследнике вместо контракта, ты можешь нарушить внутреннюю целостность объекта

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


LP>2. Что хуже всего, появляется зависимость от непубличных методов, что может выйти боком в будущем при изменении их реализации разработчиком библиотеки.


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

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


А теперь ответ на твой вопрос. Собственно, я уже его давал. Повторю

class A{};
class B{};

class A1 : A {};
class B1 : B {};

Внутри класса B1 используется класс A1. Он больше нигде не виден и не нужен. Он расширяет возможности A. Везде за пределами B1 (то есть в B , А также в других местах) экземпляры A1 выглядят как A. Виртуальности здесь нет вообще.

Аналогично, внутри B2 может использоваться A2 и т.д. Или A1. Или A. В зависимосчти от того, что надо.

Имеем стройную иерархию. Тот, кто это захочет использовать, может взять A и не обращать внимания на его расширения. Или A1, при этом он не обязан помнить про его происхождение от A. Или A2. И т.д. А не иметь дело с несколькими хелперами, возможно, противоречащими друг другу. Автор A1 ведь продкмал его происхождение от A, а автор A2 — от A1, в то время как авторы хелперов совсем не обязаны думать ни о согласовании, ни о недублировании. И кроме того, если уж я нашел (поиском хотя бы) класс A5, значит, я имею все публичное от A1,A2,A3,A4. А хелперы — где они, сколько их, какие они, как их искать... Никакой логики в них нет.

В общем, полиморфизм без наследования невозможен, а вот наследование без полиморфизма

LP>Люди, привыкшие к такой ублюдочной библиотеке, как MFC, могут выдержать многое. В этом случае никакой это не критерий.


Люди, считающие, что аргументы такого рода вообще являются аргументами, вряд ли заслуживают того, чтобы их аргументы всерьез обсуждались. Тавк что лучше сними это заявление.
With best regards
Pavel Dvorkin
Re[21]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.12.08 05:03
Оценка: 32 (2) +2
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>1. Автор фреймворка Moq говорит, что запечатанные классы — не рулят. По крайней мере первый пункт железобетонный — запечатанный класс невозможно мОкнуть обычными средствами.
Это никак не противоречит тем максимам, которые вызвали столь бурную реакцию у Павла Дворкина. Фишка в том, что именно наследование реализации может вызывать неожиданные спецэффекты. А вот реализация интерфейса — нет. Поэтому совершенно нормально иметь sealed class, реализующий целую пачку интерфейсов.


LCR>2. Как реализовать идею escaped string? Смысл в том, что обычный String передавать нельзя в некоторые места без предварительной "эскепизации", однако в остальных случаях это нормальная строка:

LCR>
LCR>class EscapedString : String { ... }
LCR>class UnescapedString : String { ... }

Прекрасный пример. Вот как раз наследование для него - худший вариант. 
Просто потому, что "в остальных случаях" EscapedString - вовсе не "нормальная строка". В частности, операции взятия подстроки и замены символов приведут к тому, что результат перестанет быть EscapedString. 
Есть пара исключений. Например, сериализация в стрим должна вести себя так же, как и в случае обычной строки. Тем не менее, говорить о каком-либо наследовании слишком смело.
Поэтому самый грамотный вариант - ввести новый тип EscapedString, который никак со строкой не связан. 
Точнее, у него должны быть определены два преобразования в строку. Примерно так:
[c#]
public class EscapedString
{
  public EscapedString(string unescaped)
    {
    }
    
  public string GetRawString(); 
    public string UnEscape();

    public static implicit operator string(EscapedString estr)
    {
      return estr.UnEscape();
    }
    public static implicit operator EscapedString(string str)
    {
      return new EscapedString(string);
    }
}

Естественно, неявные преобразования в строку и обратно делаются через ескейпинг. Для доступа к заексейпленным потрошкам нужно выполнить явный метод GetRawString(). Это гарантирует нам отсутствие побочных эффектов, в том числе, к примеру, невозможность случайно сконкатенировать EscapedString с UnescapedString, получив неприменимого монстра.

LCR>3. Как добавить к int, double етц информацию о том, что он реализует IAddable, ISubtractable, IDividable, IMultipliable? Чтобы иметь возможность написать:

LCR>Конечно, тут sealed не при чём, тут немного другая проблема.
Это проблема дизайна CLR. Точно так же, как в 2.0 задним числом добавили в int[] поддержку IEnumerable<int>, такие вещи надо было бы делать именно в CLR.
Даже в языке делать это уже поздно. Тем более в библиотеке.

LCR>Это больше относится к тому, что неплохо бы иметь больше рукояток
Автор: Lazy Cjow Rhrr
Дата: 14.12.08
для воздействия на стандартные классы.

То, что ты предлагаешь — это фактически накат патчей на CLR. Которые, в том числе, будут страдать от всё тех же зависимостей от деталей реализации.
Если интересуют compile-time возможности, работающие без правок CLR, то нужно смотреть на Nemerle или F#.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: Override для произвольного метода.
От: LaPerouse  
Дата: 15.12.08 08:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


LP>>А зачем наследование от библиотечного класса без полиморфизма? Назови, пожалуйста, хоть одно преимущества. Недостатки очевидны:

LP>>1. Пользуясь protected-методами в наследнике вместо контракта, ты можешь нарушить внутреннюю целостность объекта

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


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

>>Но ведь и там нарушить внутреннюю целостность объекта тоже возможно


Об этом в исходном посте я тоже написал:
"На эти издержки можно идти, если мы получаем преимущества ввиде полиморфного поведения, но в остуствии таких преимуществ это бесмысленно и вредно."

>>даже и легче


Почему это легче? Я разницы не вижу, почему — см. выше.

LP>>2. Что хуже всего, появляется зависимость от непубличных методов, что может выйти боком в будущем при изменении их реализации разработчиком библиотеки.


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


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


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


PD>А теперь ответ на твой вопрос. Собственно, я уже его давал. Повторю


PD>class A{};

PD>class B{};

PD>class A1 : A {};

PD>class B1 : B {};

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


PD>Аналогично, внутри B2 может использоваться A2 и т.д. Или A1. Или A. В зависимосчти от того, что надо.


То есть ты говоришь о чем-то таком:

class A
{
    public String toString()
    {
        return "A";
    }
}

class B
{
    A a;
    
    public A getA()
    {
        return a;
    }
    
    public B(A a)
    {
        this.a=a;
    }
    
    public String toString()
    {
        return "B:" + getA().toString();
    }
}

class A1 : extends A
{
    public String toString()
    {
        return "A1";
    }
}

class B1 : extends B
{
    public B1(A1 a)
    {
        super(a)
    }
    
    String toString()
    {
        return "B1:" + getA().toString();
    }
}


Или я неправильно тебя понял?

PD>Имеем стройную иерархию. Тот, кто это захочет использовать, может взять A и не обращать внимания на его расширения. Или A1, при этом он не обязан помнить про его происхождение от A. Или A2. И т.д. А не иметь дело с несколькими хелперами, возможно, противоречащими друг другу. Автор A1 ведь продкмал его происхождение от A, а автор A2 — от A1, в то время как авторы хелперов совсем не обязаны думать ни о согласовании, ни о недублировании. И кроме того, если уж я нашел (поиском хотя бы) класс A5, значит, я имею все публичное от A1,A2,A3,A4. А хелперы — где они, сколько их, какие они, как их искать... Никакой логики в них нет.


PD>В общем, полиморфизм без наследования невозможен, а вот наследование без полиморфизма


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

A a = new A1();
B b = new B1();
b.toString();


Если же речь идет о т. н. "полиморфизме без наследования", то бишь о простом повторном использовании, то в данном случае идет речь о повторном использовании тех методов для работы с объектом класса A1 по интерфейсу A, которые есть в B. То есть именно для их использования ты порождаешь класс B1, наследующийся от B. В примере выше у тебя налицо повторное использование метода getA(). При этом ты получаешь доступ и к protected-методам класса B. Если тебе не нужно полиморфное поведение объекта класса B1, то вместо преусловутого "наследования без полиморфизма" лучше сделать так:

class B1
{
    B b;
    
    public toString()
    {
        return "B1:" + b.getA().toString();
    }
}


Зато в этом случае ты имеешь дело с инстансом B через его открытый интерфейс. Попробуй возрази против этого примера, чем твой случай, изображенный самым первым, лучше вот этого последнего?

LP>>Люди, привыкшие к такой ублюдочной библиотеке, как MFC, могут выдержать многое. В этом случае никакой это не критерий.


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


Да не заявление это и не аргумент вовсе, а, скажем так, комментарий человека, который использовал эту библиотеку. Если хочешь — не обращай на это внимания.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[23]: Override для произвольного метода.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 15.12.08 09:09
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А теперь ответ на твой вопрос. Собственно, я уже его давал. Повторю


PD>class A{};

PD>class B{};

PD>class A1 : A {};

PD>class B1 : B {};

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

А класс B1 где используется? Если он используется неполиморфно, то он сам может быть заменен классом-хелпером или аггрегацией.
Если рассматривать не сферического коня в вакууме, а рельный код, то окажется что наследования без полиморфизма почти всегдпа возможно заменить хелперами или аггрегацией. Аггрегация гораздо больше соотвествует принципам хорошего ОО-дизайна, таким как Interface Segregation Principle и Dependency Injection Principle.

PD>В общем, полиморфизм без наследования невозможен, а вот наследование без полиморфизма

Моя плакать...

LP>>Люди, привыкшие к такой ублюдочной библиотеке, как MFC, могут выдержать многое. В этом случае никакой это не критерий.

PD>Люди, считающие, что аргументы такого рода вообще являются аргументами, вряд ли заслуживают того, чтобы их аргументы всерьез обсуждались. Тавк что лучше сними это заявление.
Зря ты так говоришь. Люди часто путают удобство\правильность и привычность. Если кому-то привычно писать на MFC и в духе MFC, то не значит так писать правильно.
Есть принципы и паттерны проектирования ПО, следование которым дает вполне определенные преимущества (выявленные анализом многих программ). А ты пытаешься показать что нарушение принципов может дать какие-то преимущества, причем доказательства сводятся к примерам библиотек (возможно очень тебе привычных), нарушающих эти принципы.
Re[23]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 15.12.08 09:52
Оценка: +3
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Все, дальше не стоит обсуждать.

Что ж, слив засчитан. Вообщем-то ожидалось, что ничего внятного ты больше не скажешь.. )

PD>http://img.meta.ua/rsdnsearch/?q=codeproject&amp;mode=rank&amp;group=5

PD>1194 ссылки только в форуме mfc
PD>http://img.meta.ua/rsdnsearch/?q=codeproject&amp;mode=rank&amp;group=N
PD>6423 ссылки всего.
Каким образом количество ссылок может влиять на качество кода? Самому не смешно?

PD>При таком уровне понимания дискутировать смысла просто нет.

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

PD>Предлагаю тебе сделать следующее. Выложи свои рассуждения насчет поделок на codeproject в форум MFC. Посмотрим на реакцию.

Мне здешнего паноптикума хватает, зачем я еще вражеский ресурс популяризовавать буду?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[23]: offtop
От: LaPerouse  
Дата: 15.12.08 10:10
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


4>>Практика бывает плохая и хорошая, собственно как и теория, и MFC приводить в качестве примера хорошей практики очень сомнительно.


PD>MFC, конечно, устарела по концепциям, но по качеству кода (в рамках своих концепций) — она на порядок лучше. Во всяком случае, такого безобразия, как пересоздания listview с переливанием данных ради того, чтобы установить флаг сортировки, там не найдешь.


MFC — просто куча слобоструктурированного кода, по сути, это тончайшая обертка на ситсемным апи, приправленная макросами, проектирования там ноль — просто нет. Говорить о каких-то там концепциях MFC просто смешно. Нет там никаких концепций, нет там никаких идей.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[23]: offtop
От: 4058  
Дата: 15.12.08 10:19
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


4>>Практика бывает плохая и хорошая, собственно как и теория, и MFC приводить в качестве примера хорошей практики очень сомнительно.


PD>MFC, конечно, устарела по концепциям, но по качеству кода (в рамках своих концепций) — она на порядок лучше.


Она не устарела по концепциям, т.к. оных посто нет, это тонкая обертка над WINAPI.
Модно было в то время переходить на C++, без малейшего представления о ООП.
В результате чего сформировался негласный диалет "C с классами".

Было:

struct HDC;
struct HWND;
HDC GetDC(HWND)


Стало:

class CWND
{
    CDC* GetDC()
}


Лично, для меня это одно и тоже.

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


Я правильно понимаю, что речь идет о System.Windows.Forms.ListView?
Re[24]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.12.08 10:26
Оценка: +3 :)
Здравствуйте, LaPerouse, Вы писали:

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

Не-не-не. Я не настолько фанатичен. Речь всего лишь о том, что разрешать наследование реализации нужно с большой осторожностью, вот и всё. Совсем его изничтожить не получится (да и не нужно).
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: offtop
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.12.08 10:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>MFC, конечно, устарела по концепциям, но по качеству кода (в рамках своих концепций) — она на порядок лучше.


Лучше чего?
... << RSDN@Home 1.2.0 alpha 4 rev. 1120 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[23]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.12.08 11:01
Оценка: +3
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Предлагаю тебе сделать следующее. Выложи свои рассуждения насчет поделок на codeproject в форум MFC. Посмотрим на реакцию.
Павел, демократическое голосование не может служить методом решения технических вопросов.

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

И не стоит сводить решение вопроса о том, хорошо ли сделан класс CStringEx, к вопросу о дискредитации codeproject. На нём есть вполне вменяемые поделки, как впрочем и килотонны мусора.

Надо применять либо собственный мозг к анализу решений, либо обращаться к людям, которые разбираются в предмете.
Членство на codeproject не даёт никаких гарантий профессионализма:

The author of CStringEX should run Purify(memory checker) on CStringEx. It particularly complains about writing out of bounds in the Delete() function.

(http://www.codeguru.com/forum/archive/index.php/t-42810.html)

Вот, к примеру, типичная проблема, которую огребает наивный пользователь унылых CxxxEx:
http://static.dreamincode.net/forums/showtopic5723.htm
Увы, за шесть лет никто не смог дать ему внятный ответ.

Вот что бывает с теми, кто неосторожно наследуется от чужого кода:
http://www.experts-exchange.com/Programming/Languages/CPP/Q_22500053.html

Я не смог найти ни одного примера применения этого CStringEx. Наверное, плохо искал. Либо он просто никому нафиг не нужен.
Зато нашел другой CStringEx. Опять же, бедному пользователю придется как-то выбирать одну из этих строк, либо руками мерджить реализации. Если бы это были хелперные функции, никакой проблемы бы не возникло. Увы, понять это люди, укушенные MFC, могут только с большим напряжением всех усилий.

Вот еще один букет поделок на основе CString: http://69.10.233.10/KB/string/stringtable.aspx
Такое впечатление, что эти люди реально не знают другого способа программировать, кроме как наследоваться от строки.
То есть чувак изобретает целый новый класс CMsg чтобы писать вот так:
SetWindowText(CMsg(IDS_MYSTRING)); // This is straightforward!

То, что это заработает безо всякого класса, ему недоступно:
СString CMsg(int resourceID)
{
  return CString(MAKEINTRESOURCE(resourceID));
}

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

Впрочем, достаточно прочесть его рекомендацию использовать числовые идентификаторы вместо мнемонических констант, чтобы сделать однозначный вывод о его уровне как архитектора.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 15.12.08 11:43
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В общем, полиморфизм без наследования невозможен, а вот наследование без полиморфизма

Павел, ты бы прежде чем рассуждать про ООП, наследование и правильность MFC, хоть основы бы выучил, а то вообще как-то не серьезно. =)
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[22]: Override для произвольного метода.
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 16.12.08 09:20
Оценка:
Sinclair,

S>Прекрасный пример. Вот как раз наследование для него — худший вариант. Просто потому, что "в остальных случаях" EscapedString — вовсе не "нормальная строка". В частности, операции взятия подстроки и замены символов приведут к тому, что результат перестанет быть EscapedString.

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

Еще пожалуй ToUpper/ToLower для некоторых типов эскейпинга. Но конечно таких "совсем одинаковых" операций для обычной и необычной строки немного. С фразой "в остальных случаях ведёт как обычная строка" я конечно поторопился. Нужно добавить ещё "если перекрыть методы взятия подстроки и замены символов". Теперь уже EscapedString не столь ущербный класс, как казалось ранее См. ниже.

S>Поэтому самый грамотный вариант — ввести новый тип EscapedString, который никак со строкой не связан.

S>Точнее, у него должны быть определены два преобразования в строку. Примерно так:
public class EscapedString { ... }

S>Естественно, неявные преобразования в строку и обратно делаются через ескейпинг. Для доступа к заексейпленным потрошкам нужно выполнить явный метод GetRawString(). Это гарантирует нам отсутствие побочных эффектов, в том числе, к примеру, невозможность случайно сконкатенировать EscapedString с UnescapedString, получив неприменимого монстра.

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

С другой стороны, случай со String особый, потому что
1. Строки иммутабельны, следовательно все операции которые оформлены методами ведут себя как внешние функции.
1a. Следовательно, интерфейс IString пустой, и методов, которые хочется вызвать полиморфно нет.
1б. Следовательно, "методам" String можно безопасно иметь (и они имеют) наглухо прибитую зависимость от конструкторов String(...).
2. Функция escape :: String -> EscapedString биективна, то есть можно как передать EscapedString во внешний код, так и получить его обратно конвертацией.

Суммируя эти факты вынужден прийти к выводу , что да, EscapedString лучше оформить в самостоятельный класс. Замечу только, что если найдётся sealed класс, который не удовлетворяет пунктам 1 или 2, то значит sealed там стоит неудачно.

LCR>>Это больше относится к тому, что неплохо бы иметь больше рукояток
Автор: Lazy Cjow Rhrr
Дата: 14.12.08
для воздействия на стандартные классы.

S>То, что ты предлагаешь — это фактически накат патчей на CLR. Которые, в том числе, будут страдать от всё тех же зависимостей от деталей реализации.
Да, конечно будут. Что они будут использовать, от этого и будут страдать. Но можно регулировать зависимость: использовать чисто интерфейс, или чуть-чуть реализации, или очень много реализации.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[23]: Override для произвольного метода.
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.12.08 10:39
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Еще пожалуй ToUpper/ToLower для некоторых типов эскейпинга.

Ключевой момент выделен.
LCR>Но конечно таких "совсем одинаковых" операций для обычной и необычной строки немного. С фразой "в остальных случаях ведёт как обычная строка" я конечно поторопился. Нужно добавить ещё "если перекрыть методы взятия подстроки и замены символов". Теперь уже EscapedString не столь ущербный класс, как казалось ранее См. ниже.

LCR>С одной стороны, выделяя EscapedString в отдельный класс ты ставишь крест на возможности использовать EscapedString полиморфно в классах, которые используют String, скажем библиотеку регэкспов.

С чего бы это вдруг? Ну-ка, покажи мне пример кода, на котором стоит крест.

LCR>Суммируя эти факты вынужден прийти к выводу , что да, EscapedString лучше оформить в самостоятельный класс. Замечу только, что если найдётся sealed класс, который не удовлетворяет пунктам 1 или 2, то значит sealed там стоит неудачно.

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

LCR>Да, конечно будут. Что они будут использовать, от этого и будут страдать. Но можно регулировать зависимость: использовать чисто интерфейс, или чуть-чуть реализации, или очень много реализации.

Да-да. Как раз на прошлой неделе референдум одобрил выдачу героина швейцарским наркоманам за государственный счет. Вот она, регулировка зависимости в полный рост.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[24]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 16.12.08 10:50
Оценка: :))
Здравствуйте, IB, Вы писали:

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


PD>>Все, дальше не стоит обсуждать.

IB>Что ж, слив засчитан. Вообщем-то ожидалось, что ничего внятного ты больше не скажешь.. )

Глупо.

PD>>http://img.meta.ua/rsdnsearch/?q=codeproject&amp;mode=rank&amp;group=5

PD>>1194 ссылки только в форуме mfc
PD>>http://img.meta.ua/rsdnsearch/?q=codeproject&amp;mode=rank&amp;group=N
PD>>6423 ссылки всего.
IB>Каким образом количество ссылок может влиять на качество кода? Самому не смешно?

PD>>При таком уровне понимания дискутировать смысла просто нет.

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

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


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


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

PD>>Предлагаю тебе сделать следующее. Выложи свои рассуждения насчет поделок на codeproject в форум MFC. Посмотрим на реакцию.

IB>Мне здешнего паноптикума хватает, зачем я еще вражеский ресурс популяризовавать буду?

Популяризовать ? Где ? В форуме MFC ? Там его популяризовать не надо, он там и так известен. А вот себя ты точно там так отпопуляризуешь, если с таким заявлением выступишь, что я тебе не завидую

А насчет вражеского ресурса — вот это, скорее всего, и есть истина. Видимо, для тебя те, кто не принимают твои концепции (ваши концепции) — враги. Ну что же...
With best regards
Pavel Dvorkin
Re[24]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 16.12.08 10:53
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>На Codeproject таки, действительно, полно поделок. Их там как раз большая часть и есть.


Там все есть. И поделки, и серьезные вещи. Впрочем — давай сюда другой, более серьезный ресурс общего назначения, скажу спасибо. А пока что основное, что я вижу — это codeproject, codeguru. Для Delphi был еще какой-то сайт с собачьим именем, забыл название.
With best regards
Pavel Dvorkin
Re[25]: Override для произвольного метода.
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.12.08 11:20
Оценка: +2 -1
Здравствуйте, Pavel Dvorkin, Вы писали:

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


Фи. Детский сад, штаны на лямках.
... << RSDN@Home 1.2.0 alpha 4 rev. 1120 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[25]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 16.12.08 11:30
Оценка: +3
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Глупо.

Вот и я говорю, глупо ты себя ведешь Павел, глупо и не дальновидно.

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

Ты хочешь сказать, что программисты на .Net своих классов не создают?

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

Да хоть двести. Я тебе заранее не советую меряться серьезностью вопросов и уводить разговор в эту область. У меня по любому толще и длинее, а уж на пару с Антоном у нас их вообще два, так что лучше даже не начинай.
И за всеми этими разглагольствованиями, ты так и не ответил на прямо поставленный вопрос, я все еще жду внятных аргументов, а не отсылок к крутизне проектов и левые ресурсы.

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

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

PD>Популяризовать ? Где ? В форуме MFC ? Там его популяризовать не надо, он там и так известен.

Вот именно, тебе уже объяснили, как он известен..

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

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