Я думаю, что главная проблема ООП совсем не в ООП, а в людях, которые некогда превратили его в религию. Даже в университете, как я помню, наc учили в духе, что ООП — это Единственный Истинный Путь (как любил говорить один художник: "Ein Volk, ein Reich, ein Führer"). Отсюда и проблемы. Когда же к ООП относятся просто как к ещё одному инструменту из арсенала разработчика, таких проблем не возникает.
Только, вот, это беда не только ООП — это беда нашей индустрии вообще. Периодически появляются какие-то мессии в виде отдельных людей или корпораций, которые начинают двигать очередную модную идею или технологию, провозглашая её спасением от всех наших бед (в какой уж раз!) и будущим разработки программного обеспечения. Если этот посыл подхватывается массами, то проблемы гарантированы: много людей начнет следовать новым идеям, не понимая их до конца, и тем яростнее их отстаивая, чем примитивнее их понимание. Сколько таких религий уже было и прошло! ООБД ("реляционные СУБД умрут!"), разный веб ("десктопные приложения умрут!"), виртуальные машины ("нативный код умрёт!"), разные новые языки ("С++ умрёт!") и платформы ("вообще все умрут...").
Зрелость процесса развития идеологического поля индустрии больше всего напоминает некие религиозные реформации, расколы, войны, анафемы... слово "холивар" тут как нельзя удачно подходит, верно отражает суть Что характерно, когда вера переходит в понимание (с опытом, как правило), все эти технологии убираются с пьедестала в тот самый ящик с инструментами. Не серебряная пуля, но, авось, пригодится.
Вот сейчас, например, такой "модной фишкой" является agile и scrum. Подчас его пытаются силой натянуть на те проекты, где он совсем не нужен, как тот презерватив на глобус. Опять же, проблема не в agile, проблема в тех, кто слишком уверовал в его чудодейственную силу.
Здравствуйте, 0x7be, Вы писали:
0>это беда нашей индустрии вообще. Периодически появляются какие-то мессии в виде отдельных людей или корпораций, которые начинают двигать очередную модную идею или технологию,
Я даже знаю, о какой технологии идёт речь.
0>Вот сейчас, например, такой "модной фишкой" является agile и scrum.
Здравствуйте, 0x7be, Вы писали:
0>Проблема в людях.
В жадности человеческой.
Взять к примеру тот же С++. Язык мощный, с множеством возможностей, в общем неплохой но до ужаса кривой, главным образом из-за унаследованных от си вещей. Взять хотя-бы ту же систему #include или препроцессор... Казалось бы, всем все понятно, что стоит всем крупным IT компаниям и open-source сообществу собраться и придумать новый язык — нативный, похожий на С++, но исключительно грамотно спроектированный, избавленный от всех недостатков С++ и с множеством новых полезных и грамотно спроектированных фич. Назвать его C++2, договориться о том, что в течение какого-то времени все компиляторы будут поддерживать файлы обоих типов cpp и cpp2.
Но нет. Вместо этого все упорно продолжают колоться и жрать кактусы. И еще придумывать свои языки (Java, C#). Патентовать их и судиться друг с другом.
0>>Проблема в людях.
XC>В жадности человеческой.
XC>Взять к примеру тот же С++. Язык мощный, с множеством возможностей, в общем неплохой но до ужаса кривой, главным образом из-за унаследованных от си вещей. Взять хотя-бы ту же систему #include или препроцессор... Казалось бы, всем все понятно, что стоит всем крупным IT компаниям и open-source сообществу собраться и придумать новый язык — нативный, похожий на С++, но исключительно грамотно спроектированный, избавленный от всех недостатков С++ и с множеством новых полезных и грамотно спроектированных фич. Назвать его C++2, договориться о том, что в течение какого-то времени все компиляторы будут поддерживать файлы обоих типов cpp и cpp2.
XC>Но нет. Вместо этого все упорно продолжают колоться и жрать кактусы. И еще придумывать свои языки (Java, C#).
C++ кривой в следствие своей мощности. Хотите грамотно спроектированный, избавленный от всех недостатков С++ и с множеством новых полезных и грамотно спроектированных фич — C# и java к Вашим услугам, хотите нативный, похожий на С++ и относительно простой — шаг назад к Си.
Причем здесь жадность?
Поймите, люди работающие в крупных ИТ компаниях не дураки, они прекрасно понимают что C++ 2 закончиться все тем же C++ 1. Здесь как обычно все сводится к компромиссам.
Здравствуйте, 0x7be, Вы писали:
0>Вот сейчас, например, такой "модной фишкой" является agile и scrum. Подчас его пытаются силой натянуть на те проекты, где он совсем не нужен, как тот презерватив на глобус. Опять же, проблема не в agile, проблема в тех, кто слишком уверовал в его чудодейственную силу.
Уже года 2-3 как нет. Отстал ты от тренда. Сейчас рулят облака и мобайл.
Здравствуйте, 0x7be, Вы писали:
0>Здравствуйте, Mystic, Вы писали:
M>>Конкретнее, в догматиках. 0>Не только. Восторженные юноши, окрыленные передовыми идеями, тоже вносят свою лепту
Юноши — догматики
Догматизм способ мышления, оперирующий догмами (считающиеся неизменными вечными положениями, не подвергаемых критике) и опирающийся на них.
Для догматизма характерны некритичность по отношению к догмам (отсутствие критики и сомнений) и консерватизм мышления (неспособность воспринимать информацию, противоречащую догмам), слепая вера в авторитеты.
Здравствуйте, Mystic, Вы писали:
M>Юноши — догматики M>
M>Догматизм способ мышления, оперирующий догмами (считающиеся неизменными вечными положениями, не подвергаемых критике) и опирающийся на них.
M>Для догматизма характерны некритичность по отношению к догмам (отсутствие критики и сомнений) и консерватизм мышления (неспособность воспринимать информацию, противоречащую догмам), слепая вера в авторитеты.
Здравствуйте, 0x7be, Вы писали:
0>Я думаю, что главная проблема ООП совсем не в ООП, а в людях, которые некогда превратили его в религию.
А я думаю, что главная проблема ООП — в мифологии. Мы сейчас наблюдаем крайне интересную картину во многих областях программирования, включая и ООП: засилье мисконцепций (не знаю правильное слово на русском языке).
Ну то есть берётся какая-нибудь вполне разумная вещь, и начинает доводиться до абсурда. И этот абсурд каким-то непонятным мне образом проникает в популярную литературу.
Например, очень много "учебников ООП" предлагают в качестве примера иерархии классов иерархию геометрических фигур. Опытным разработчикам понятно, что
а) в реальных программах так никто никогда не делает — требования к ним исключают использование иерархии фигур
б) получить математически корректную иерархию фигур вообще невозможно — гуглить срачи по "наследованию прямоугольника от квадрата"
Неопытные разработчики принимают этот бред за чистую монету, откуда происходит злоупотребление ООП.
Очень мало литературы упирает на поведение в поисках иерархий наследования, и много — на состояние. Редкий частный случай, когда имеет смысл наследовать реализацию, а не интерфейс, выдаётся за основное применение.
В итоге мы имеем разрыв между тем, чему учат в учебниках и тем, что стоит применять на практике. Отсюда и весь этот горький катаклизм, который мы наблюдаем.
Не думаю, что ООП слишком в этом специфично. Просто сейчас оно в мейнстриме, и заметнее всего бред именно в нём. Когда ФП окажется в мейнстриме и обрастёт своими мифами, мы, скорее всего, будем наблюдать то же самое.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, x-code, Вы писали:
XC>Здравствуйте, 0x7be, Вы писали:
XC>Взять к примеру тот же С++. Язык мощный, с множеством возможностей, в общем неплохой но до ужаса кривой, главным образом из-за унаследованных от C ... но исключительно грамотно спроектированный, избавленный от всех недостатков С++ и с множеством новых полезных и грамотно спроектированных фич.
Одно время казалось, что язык D претендует на эту роль. Сейчас же на его развитие без слез взглянуть нельзя.
После появления C++11 нативному любому нативному "наследнику" будет очень тяжело. Тот же D, кажется, окончательно упустил свой шанс.
Здравствуйте, 0x7be, Вы писали:
0>Я думаю, что главная проблема ООП совсем не в ООП, а в людях, которые некогда превратили его в религию.
Если под ООП понимать то, что мы имеем в C++/Java/C#, то думаю, что главная проблема все же в ООП.
Трудности появляются сразу, на самых простых задачах; так из-за отсутствия мультиметодов попытка определения любой операции требующей полиморфизма более чем по одному параметру превращаются в вырезание гландов автогеном через понятно что. Посмотрите как реализуются операции equals на Java или Equals на C#. Если реализация такой простой и фундаментальной операции требует каких-то ненулевых усилий, такая парадигма программирования почти всегда приносит больше вреда чем пользы.
Здравствуйте, igna, Вы писали:
I>Если под ООП понимать то, что мы имеем в C++/Java/C#, то думаю, что главная проблема все же в ООП. I>Трудности появляются сразу, на самых простых задачах; так из-за отсутствия мультиметодов попытка определения любой операции требующей полиморфизма более чем по одному параметру превращаются в вырезание гландов автогеном через понятно что. Посмотрите как реализуются операции equals на Java или Equals на C#. Если реализация такой простой и фундаментальной операции требует каких-то ненулевых усилий, такая парадигма программирования почти всегда приносит больше вреда чем пользы.
Боюсь, мы говорим совершенно о разных вещах.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, 0x7be, Вы писали:
0>>Я думаю, что главная проблема ООП совсем не в ООП, а в людях, которые некогда превратили его в религию. S>А я думаю, что главная проблема ООП — в мифологии. Мы сейчас наблюдаем крайне интересную картину во многих областях программирования, включая и ООП: засилье мисконцепций (не знаю правильное слово на русском языке)...
Я примерно о том же говорю. Чем поверхностнее понимание парадигмы, тем больше вокруг неё мифов и верований и меньше понимания границ её применимости.
Здравствуйте, 0x7be, Вы писали:
0>Боюсь, мы говорим совершенно о разных вещах.
Ну почему же, мы с тобой отвечаем на один и тот же вопрос: в чем главная проблема ООП, в ООП или в людях. Отвечаем по разному, да, но это не означает, что говорим мы о разных вещах.
Здравствуйте, igna, Вы писали:
I>Какую такую мощность дало языку использование слова const в двух целях, как read-only и как собственно constant?
Это как раз кривизна.
Здравствуйте, Mystic, Вы писали:
M>Здравствуйте, 0x7be, Вы писали:
0>>Здравствуйте, Mystic, Вы писали:
M>>>Конкретнее, в догматиках. 0>>Не только. Восторженные юноши, окрыленные передовыми идеями, тоже вносят свою лепту
M>Юноши — догматики
юношей вон из разработки ПО
(индустрия страдает)
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Sinclair, Вы писали: S>Здравствуйте, 0x7be, Вы писали:
0>>Я думаю, что главная проблема ООП совсем не в ООП, а в людях, которые некогда превратили его в религию. S>А я думаю, что главная проблема ООП — в мифологии... S>абсурд каким-то непонятным мне образом проникает в популярную литературу. S>Например, очень много "учебников ООП" .... S>Неопытные разработчики принимают этот бред за чистую монету, откуда происходит...
Да, ООП здесь можно заменить на что угодно.
Незрелая область деятельности, авторы "учебников" выдают субъективное мнение за истину, хотя и пишут не о сути мироздания, а об интсрументах и способах решения задач, преподносят своё понимание хорошего и плохого.
S>Редкий частный случай, когда имеет смысл наследовать реализацию, а не интерфейс, выдаётся за основное применение.
Не согласен. Наследование реализации способно во многих случаях сократить кол-во кода, дублирование, а следовательно и сложность. Пример: представим класс A, для которого планируется сделать торчу наследников
abstract class A
{
protected abstract bool MyMethod1();
public int PublicMethod1 ()
{
//...
if (MyMethod1())..
//....
}
}
А вот хороший интерфейс дорогого стоит. Чтобы создать пачку годных интерфейсов нужно нехилые скилы иметь.
(Сам неоднократно писал throw new NotSupportedException())
S>В итоге мы имеем разрыв между тем, чему учат в учебниках и тем, что стоит применять на практике. Отсюда и весь этот горький катаклизм, который мы наблюдаем.
А наблюдаем мы на практике то, что было когда-то в учебнике
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, igna, Вы писали:
I>Трудности появляются сразу, на самых простых задачах; так из-за отсутствия мультиметодов попытка определения любой операции требующей полиморфизма более чем по одному параметру превращаются в вырезание гландов автогеном через понятно что.
К слову, мультиметоды в C# можно эмулировать с помощью dynamic-а. Правда такие методы будут вызваться раз в 10-20 медленнее обычных.
Здравствуйте, hardcase, Вы писали:
H>К слову, мультиметоды в C# можно эмулировать с помощью dynamic-а. Правда такие методы будут вызваться раз в 10-20 медленнее обычных.
Унаследовано-то все-равно все от Object со всеми вытекающими Equals. Образно говоря, бочка говна останется бочкой говна даже если в нее положить пару ложек меда.
Ф>abstract class A
Ф>{
Ф>protected abstract bool MyMethod1();
Ф>public int PublicMethod1 ()
Ф> {
Ф> //...
Ф> if (MyMethod1())..
Ф> //....
Ф> }
Ф>}
Так это же главный объектно-ориентированный антипаттерн!
Вместо того, чтобы параметризировать функцию PublicMethod1 параметром функционального типа MyMethod1 (хотя бы по аналогии со стандартным qsort древнего языка C), устраивается этот выворот кишок.
Здравствуйте, x-code, Вы писали:
XC>Но нет. Вместо этого все упорно продолжают колоться и жрать кактусы. И еще придумывать свои языки (Java, C#). Патентовать их и судиться друг с другом.
Я вот хочу придумать качественный стандарт на стэк язык/промежуточный бинарный код/виртуальная машина для этого бинарного кода/ОС где всё на этом бинарном коде.
Только скажем синтаксис у меня более многословный выходит, а хочешь лаконичности — будет C++|C# а в этом (особенно в связи с C#) случае возможны патентные тролленги.
Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, x-code, Вы писали:
S>C++ кривой в следствие своей мощности. Хотите грамотно спроектированный, избавленный от всех недостатков С++ и с множеством новых полезных и грамотно спроектированных фич — C# и java к Вашим услугам, хотите нативный, похожий на С++ и относительно простой — шаг назад к Си. S>Причем здесь жадность? S>Поймите, люди работающие в крупных ИТ компаниях не дураки, они прекрасно понимают что C++ 2 закончиться все тем же C++ 1. Здесь как обычно все сводится к компромиссам.
Дураков везде хватает. Вот я имхо убийство Silverlight — дурость несусветная со стороны Microsoft, я считаю.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Философ, Вы писали:
I>Так это же главный объектно-ориентированный антипаттерн!
I>Вместо того, чтобы параметризировать функцию PublicMethod1 параметром функционального типа MyMethod1 (хотя бы по аналогии со стандартным qsort древнего языка C), устраивается этот выворот кишок.
?? не понял
1) чем не нравится
2) как и чем параметризировать
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Философ, Вы писали:
Ф>>?? не понял Ф>>1) чем не нравится Ф>>2) как и чем параметризировать
I>Ты qsort из стандартной библиотеки C знаешь?
Здесь никакой ООПы к счастью нет. Но здесь есть как бы намек, как можно реализовать то, для чего ты использовал наследование реализации. И тогда все будет на своих местах, а не вывернуто наизнанку.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Философ, Вы писали:
I>Здесь никакой ООПы к счастью нет. Но здесь есть как бы намек, как можно реализовать то, для чего ты использовал наследование реализации. И тогда все будет на своих местах, а не вывернуто наизнанку.
ответа не увидел
Ф>1) чем не нравится
с каких пор это стало антипаттерном?
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>с каких пор это стало антипаттерном?
Не стало, а всегда было. Твой MyMethod1 надо сделать интерфейсом и добавить параметр типа этого интерфейса методу PublicMethod1. И все, никакого наследования реализации как не бывало. Проще — значит лучше, а все что не по делу усложняет программу является антипаттерном.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Философ, Вы писали:
Ф>>с каких пор это стало антипаттерном?
I>Не стало, а всегда было. Твой MyMethod1 надо сделать интерфейсом
OK
interface IB
{
bool MyMethod1();
}
I> и добавить параметр типа этого интерфейса методу PublicMethod1.
с какой целью?
abstract class A<TIB> where TIB:IB
{
public int PublicMethod1<TIB> ()
{
//Зачем мне здесь понадобился TIB, что мне теперь с ним делать?
//...if (<????????????????????????>.MyMethod1())..
//....
}
}
Попробуем по другому...
abstract class A
{
public int PublicMethod1 (IB p_ib)
{
//...if (p_ib.MyMethod1())..
//....
}
}
Замечательно! Что получили?
Данные по прежнему остались в абстрактном классе A, из него вынесли один protected метод из N...
ОК, вынесли все N методов (вероятно, наплодив N интерфейсов).
Чем стало лучше?
I>Проще — значит лучше...
Не вижу здесь никакой простоты
I>а все что не по делу усложняет программу является антипаттерном.
Не согласен. Я вообще не знаю что такое антипаттерн. Если под словом паттерн понимать название общепринятого способа решать задачу (или способ решения, без имени), то антипаттерн — общепринятое отрицательное мнение о способе решения задачи.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали: Ф>Да, ООП здесь можно заменить на что угодно. Ф>Незрелая область деятельности, авторы "учебников" выдают субъективное мнение за истину, хотя и пишут не о сути мироздания, а об интсрументах и способах решения задач, преподносят своё понимание хорошего и плохого.
Да вроде бы не то, чтобы незрелая. Просто городские легенды кочуют из одного учебника в другой. Все эти объекты "автомобиль" с наследниками "грузовой автомобиль" — полная ерунда, которая учит вредным идеям.
S>>Редкий частный случай, когда имеет смысл наследовать реализацию, а не интерфейс, выдаётся за основное применение. Ф>Не согласен. Наследование реализации способно во многих случаях сократить кол-во кода, дублирование, а следовательно и сложность.
С чем конкретно вы несогласны? Ф>Пример: представим класс A, для которого планируется сделать торчу наследников
Не вижу примера. Вижу применение паттерна "шаблонный метод", без комментариев о том, зачем, собственно, это нужно, и почему вы хотите именно наследоваться.
Понятно, что вы хотите дать возможность наследнику переопределять метод MyMethod(). Но непонятно, почему вы требуете для этого именно наследования.
Рассмотрим более реалистичный пример: коллекцию и метод для подсчёта её длины:
public abstract IEnumerator<T> GetEnumerator();
public int Count
{
get
{
var count = 0;
foreach(var item in this) count++;
return count;
}
}
Вот этот наивный подход требует от нас ажно наследоваться от специфического класса только ради того, чтобы повторно использовать метод подсчёта Count.
Как мы знаем, в реальных решениях применяют значительно более слабую связность — строят внешний extension method Count(), который работает с любым IEnumerable, а не только с тем, который нам предоставил наследник.
Вот и в вашем примере можно избавиться от избыточного требования наследоваться от вашего базового класса при помощи банальной рокировки:
interface IA
{
bool MyMethod1();
}
...
public static int PublicMethod1(this IA a)
{
//...if (a.MyMethod1())..
//....
}
Или вообще отказаться от статической типизации и требования реализации интерфейса, которое ограничивает применение в PublicMethod1 классов из посторонних библиотек:
public static int PublicMethod1(Func<bool> a)
{
//...if (a())..
//....
}
Видите, как резко расширяется сфера возможного применения вашего PublicMethod. Вы же хотели повторного использования? Ну так наследование максимально ограничивает его вохможности.
S>>В итоге мы имеем разрыв между тем, чему учат в учебниках и тем, что стоит применять на практике. Отсюда и весь этот горький катаклизм, который мы наблюдаем.
Ф>А наблюдаем мы на практике то, что было когда-то в учебнике
Не, на практике мы наблюдаем результаты неудачных попыток применять учебные примеры, разбившихся о рифы суровой реальности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали: S>Здравствуйте, Философ, Вы писали: S>>>Редкий частный случай, когда имеет смысл наследовать реализацию, а не интерфейс, выдаётся за основное применение. Ф>>Не согласен. Наследование реализации способно во многих случаях сократить кол-во кода, дублирование, а следовательно и сложность. S>С чем конкретно вы несогласны?
С утверждением "смысл наследовать реализацию — редкий частный случай". Отнюдь не редкий. Ф>>Пример: представим класс A, для которого планируется сделать торчу наследников S>Не вижу примера. Вижу применение паттерна "шаблонный метод"
Посмотрел описание паттерна. Да это именно он и есть S>, без комментариев о том, зачем, собственно, это нужно, и почему вы хотите именно наследоваться.
Виноват.
Попробую исправится.
Собственно паттерн "шаблонный метод" был мною найден случайно, в процессе попыток упросить код и уменьшить дублирование. О паттернах проектирования я тогда только слышал.
!) Предпосылки:
interface IA
{
void PublicMethod1 ();
}
Классов, реализующих этот интерфейс планировалось великое множество, и было кое-что, что их объединяло:
а) одинаковые приватные поля
б) одинаковые реализации некоторых (!) приватных приватных методов
в) одинаковая реализация публичного метода
Иллюстрация:
Скрытый текст
//Реализация метода Method2() в этих классах отличается,
//но в рамках решаемой задачи присутствует он во всех классах с интерфейсом IAclass A1 : IA
{
private bool SomeType m_SomeField;
private bool Method1 ()
{
//Use m_SomeField
}
private bool Method2 ()
{
}
void PublicMethod1 ()
{
//Use Method1
}
}
class A2 : IA
{
private bool SomeType m_SomeField;
private bool Method1 ()
{
//Use m_SomeField
}
private bool Method2 ()
{
}
void PublicMethod1 ()
{
//Use Method1
}
}
class AN : IA
{
private bool SomeType m_SomeField;
private bool Method1 ()
{
//Use m_SomeField
}
private bool Method2 ()
{
}
void PublicMethod1 ()
{
//Use Method1
}
}
Таким образом интерфейс был заменён на абстрактный класс.
abstract class IA
{
protected abstract bool Method2 ();
public void PublicMethod1 ()
{
}
protected bool SomeType m_SomeField;
protected bool Method1 ()
{
//Use m_SomeField
}
}
S>Понятно, что вы хотите дать возможность наследнику переопределять метод MyMethod(). Но непонятно, почему вы требуете для этого именно наследования.
Наследование здесь позволило убрать дублирование кода.
S>Вы же хотели повторного использования?
Нет, я не хотел повторного использования. Целью было упрощение кода и исключение дублирования, повторное было побочным продуктом.
//Сорри, осилил не всё.
//Чуть позже продолжу.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Философ, Вы писали:
Ф>>Данные по прежнему остались в абстрактном классе A, из него вынесли один protected метод из N...
I>Так данные-то тоже вынести надо. В класс имплементирующий интерфейс.
Здравствуйте, Sinclair, Вы писали:
S>Ну то есть берётся какая-нибудь вполне разумная вещь, и начинает доводиться до абсурда. И этот абсурд каким-то непонятным мне образом проникает в популярную литературу.
... S>Очень мало литературы упирает на поведение в поисках иерархий наследования, и много — на состояние. Редкий частный случай, когда имеет смысл наследовать реализацию, а не интерфейс, выдаётся за основное применение.
"Абсурд" этот ни в какую литературу по ООП не проник, он в ней был с самого начала, по крайней мере со времени популяризации C++. Не надо теперь делать вид, будто все было бы хорошо, если бы не некие абсурдописатели, иначе к последним нужно отнести самого Страуструпа, унаследовал же он Circle от Shape на первых же страницах своей The C++ Programming Language. Далее, Гослинг при разработке Java выкинул множественное наследование, но оставил наследование реализации очевидно отнюдь не считая последнее "редким частным случаем".
Здравствуйте, igna, Вы писали:
I>"Абсурд" этот ни в какую литературу по ООП не проник, он в ней был с самого начала, по крайней мере со времени популяризации C++. Не надо теперь делать вид, будто все было бы хорошо, если бы не некие абсурдописатели, иначе к последним нужно отнести самого Страуструпа, унаследовал же он Circle от Shape на первых же страницах своей The C++ Programming Language.
Я не понял. Вы с кем не согласны — со мной или со Страуструпом?
Вы что, серъёзно полагаете, что наследование Circle от Shape — хорошая, годная идея, которая может реально применяться в какой-то программе?
I>Далее, Гослинг при разработке Java выкинул множественное наследование, но оставил наследование реализации очевидно отнюдь не считая последнее "редким частным случаем".
Хм. То есть вы полагаете, что из наличия наследования реализации в Java прямо следует то, что Гослинг не считал его редким частным случаем?
Очень интересно. Расскажите мне тогда, как он должен был поступить, если бы всё-таки считал его редким, но важным частным случаем.
И заодно расскажите, какие выводы мы можем сделать про различие подходов Гослинга и Страуструпа к различным видам наследования из наличия в Java интерфейсов и отсутствия оных в C++.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Философ, Вы писали:
Ф>С утверждением "смысл наследовать реализацию — редкий частный случай". Отнюдь не редкий.
Ф>
Ф>interface IA
Ф>{
Ф>void PublicMethod1 ();
Ф>}
Ф>
Ф>Классов, реализующих этот интерфейс планировалось великое множество, и было кое-что, что их объединяло: Ф>а) одинаковые приватные поля Ф>б) одинаковые реализации некоторых (!) приватных приватных методов Ф>в) одинаковая реализация публичного метода
Пока непонятно даже, что вас подвигло на порождение этого вашего интерфейса, т.е. чем вас не устроил делегат Action в качестве такого "интерфейса". Ф>Таким образом интерфейс был заменён на абстрактный класс.
По-прежнему непонятно, чем именно отличались все эти множественные классы, у которых одинаковые приватные члены.
Ф>Наследование здесь позволило убрать дублирование кода.
Какой именно код у вас дублировался?
Я тут уже давал ссылку на пример с TextReader.
Вот там наследование реализации уместно, т.к. наследник может выбирать, сколько методов перекрывать. Перекрыв метод побайтного чтения Read можно сразу получить работающую реализацию. Перекрытие методов ReadLine и ReadAlllines позволяет улучшить производительность наивного решения, если она не устраивает. При этом наследоваться от конкретного TextReader если хочется всего лишь немножко подправить его поведение категорически не надо — надо агрегироваться.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Я не понял. Вы с кем не согласны — со мной или со Страуструпом?
С обоими.
1. ООП, в том виде в котором его популяризировали, вещь вредная.
2. Утверждать теперь, что это, мол, и не ООП вовсе было, а так, заблуждение, а настоящее ООП вот оно, большое, розовое и пушистое; можно конечно, но на мой взгляд неприлично.
S>Вы что, серъёзно полагаете, что наследование Circle от Shape — хорошая, годная идея, которая может реально применяться в какой-то программе?
Нет, это негодная идея, если фигуры изменяемы, а в программировании в отличие от математики они как правило являются таковыми.
S>Очень интересно. Расскажите мне тогда, как он должен был поступить, если бы всё-таки считал его редким, но важным частным случаем.
Скорее всего выбросил бы как выбросил множественное наследование. Тоже ведь "редкий, но важный частный случай".
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Философ, Вы писали:
Ф>>С утверждением "смысл наследовать реализацию — редкий частный случай". Отнюдь не редкий. S>
Ф>>
Ф>>interface IA
Ф>>{
Ф>>void PublicMethod1 ();
Ф>>}
Ф>>
Ф>>Классов, реализующих этот интерфейс планировалось великое множество, и было кое-что, что их объединяло: Ф>>а) одинаковые приватные поля Ф>>б) одинаковые реализации некоторых (!) приватных приватных методов Ф>>в) одинаковая реализация публичного метода S>Пока непонятно даже, что вас подвигло на порождение этого вашего интерфейса, т.е. чем вас не устроил делегат Action в качестве такого "интерфейса".
Это стёб чтоль?
Считаете ли вы меня придурком?
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Это стёб чтоль? Ф>Считаете ли вы меня придурком?
Гыгы. В общем, ИМХО твои оппоненты просто забыли произнести слово "SRP". Но вообще, правильное решение будет зависеть от конкретной ситуации. В большинстве случаев делегат лучше, а единственный более-менее часто испольуемый паттерн, когда рулит наследование, совсем недавно вот тут неподалёку
Здравствуйте, dimgel, Вы писали:
D>Здравствуйте, Философ, Вы писали:
Ф>>Это стёб чтоль? Ф>>Считаете ли вы меня придурком?
D>Гыгы. В общем, ИМХО твои оппоненты просто забыли произнести слово "SRP".
что не так здесь с SRP?
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>что не так здесь с SRP?
С SRP всё хорошо, спасибо. Просто применение этого принципа как правило даёт кучу простых взаимодействующих объектов, в классах которых наследование реализации почти никогда не требуется. А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии. Самый часто встречающийся в моей практике пример — когда вместо того, чтобы вынести некий повторно используемый код в какой-нибудь отдельный Util, делают общий базовый класс для совершенно разнородных вещей и забабахивают этот повторно используемый код в protected-метод базового класса. Вот до отвращения уже достали это говно рефакторить, ей богу.
Здравствуйте, dimgel, Вы писали:
D>Здравствуйте, Философ, Вы писали:
Ф>>что не так здесь с SRP?
D>С SRP всё хорошо, спасибо. Просто применение этого принципа как правило даёт кучу простых взаимодействующих объектов, в классах которых наследование реализации почти никогда не требуется. D>А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии. Самый часто встречающийся в моей практике пример — когда вместо того, чтобы вынести некий повторно используемый код в какой-нибудь отдельный Util, делают общий базовый класс для совершенно разнородных вещей и забабахивают этот повторно используемый код в protected-метод базового класса. Вот до отвращения уже достали это говно рефакторить, ей богу.
Я не вижу никакой связи между наследованием и нарушением SRP. Люди склонные к этому, прекрасно справляются и без наследования, и даже без ООП: например в модуле с файловыеми операциями вполне могут оказаться функции и глобальные переменные относящиеся к графике.
SRP хотя и формулировался для ООП вполне применим за его пределами
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Я не вижу никакой связи между наследованием и нарушением SRP. Люди склонные к этому, прекрасно справляются и без наследования, и даже без ООП
Это понятно. "Все языки полны по Тьюрингу, поэтому на любом языке можно написать ужасный код." ~(c) VladD2. Но здесь обсуждалось, как надо лучше, а не хуже. А связь я в первой же строчке своего предыдущего сообщения указал.
Здравствуйте, dimgel, Вы писали:
D>Здравствуйте, Философ, Вы писали:
Ф>>Я не вижу никакой связи между наследованием и нарушением SRP.
D>А связь я в первой же строчке своего предыдущего сообщения указал.
D>А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии.
Это?
Вы мне мозг взрываете. Какое к чёрту "предпочтение"? Мы тут чем занимаемся поставленную задачу своим кодом решаем, или картину маслом пишем? Если второе, то я предпочитаю сочетание зелёного с ультрамарином.
Если же мы пишем код, то для класса не нарушающего SRP, одинаковые действия для всей иерархии, в рамках решаемой задачи, будут выделены в неприватные методы. Бывает, конечно совсем тяп-ляп: никаких отдельных методов создано не будет, а решение построено с помощью старинной китайской технологии "Copy-paste".
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>>>Я не вижу никакой связи между наследованием и нарушением SRP. D>>А связь я в первой же строчке своего предыдущего сообщения указал.
Ф> D>>А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии. Ф> Ф>Это?
Нет, вот это: "Просто применение этого принципа как правило даёт кучу простых взаимодействующих объектов, в классах которых наследование реализации почти никогда не требуется."
Ф>Вы мне мозг взрываете. Какое к чёрту "предпочтение"?
Любую более-менее сложную задачу можно решить огромным множеством разных способов. Выбор решения — это предпочтение и есть.
Здравствуйте, dimgel, Вы писали: D>Нет, вот это: "Просто применение этого принципа как правило даёт кучу простых взаимодействующих объектов, в классах которых наследование реализации почти никогда не требуется." Ф>>Вы мне мозг взрываете. Какое к чёрту "предпочтение"? D>Любую более-менее сложную задачу можно решить огромным множеством разных способов. Выбор решения — это предпочтение и есть.
А простую/несложную?
Предлагаю эксперимент: я накидаю несложную задачу, а вы её решите.
Автоматизируем магазин компьютерных комплектующих, который среди прочего торгует следующими видами товаров:
1) Процессоры
Наличие в магазине
Цена
Бренд
Название (Pentium, Core 2 Duo, Core i3, Sempron...)
Кол-во ядер
Сокет (название сокета)
Тех. процесс (кол-во нанометров)
Тип поставки (BOX/OEM)
2) Материнские платы
Наличие в магазине
Цена
Бренд
Тип памяти
Интерфейсы наличие и кол-во(AGP/PCIE/PCI/IDE/SATA)
Сокет процессора (название сокета)
Чипсет (название чипсета)
Форм-фактор (ATX, mATX, eATX...)
3) Модули памяти
Наличие в магазине
Цена
Бренд
Тип памяти
Частота памяти
Объем
4) Видеокарты
Наличие в магазине
Цена
Бренд
Название
Интерфейс подключения (AGP/PCIE/PCI)
Объём памяти
5) Жёсткие диски
Наличие в магазине
Цена
Бренд
Тип жесткого диска (Магнитный или SSD)
Объем (кол-во Гигабайт)
Интерфейс подключения (IDE / SATA / SATA II / SATA III)
Объём буферной памяти (кол-во мегобайт)
Требуется:
Написать консольную программу, по запросу выводящую подходящие покупателю товары. От программы так же требуется возможность определить совместимость компонетов выбранных покупателем. При разработке необходимо учесть, что ассортимент товаров может быть расширен.
Здесь я предлагаю написать только классы товаров, т.е. интересуют отношения между классами, их свойства и методы.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, dimgel, Вы писали:
D>Здравствуйте, Философ, Вы писали:
Ф>>Предлагаю эксперимент: я накидаю несложную задачу, а вы её решите.
D>Лениво. Когда у меня появляется свободное время, я предпочитаю разгружать мозги.
Вот так вот оказывается
Пишем сообщения на форуме не напрягая мозг...
Печально.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Вот так вот оказывается
Ага. Возьми сам реши свою задачу, выложи здесь решение и попроси того же Синклера раскритиковать в конкретике. А не напрягай других делать за тебя твою работу в целях твоего образования. Вообще оборзели. Интервьюер хренов.
Здравствуйте, Философ, Вы писали:
Ф>Требуется: Ф>Написать консольную программу, по запросу выводящую подходящие покупателю товары. От программы так же требуется возможность определить совместимость компонетов выбранных покупателем. При разработке необходимо учесть, что ассортимент товаров может быть расширен.
Ф>Здесь я предлагаю написать только классы товаров, т.е. интересуют отношения между классами, их свойства и методы.
Но это уже не задача, а решение, чего следует избегать. Заранее было решено использовать наследование для распределения данных по классам товаров. А для реальной задачи никто так делать не будет.
Здравствуйте, dimgel, Вы писали:
D>Возьми сам реши свою задачу, выложи здесь решение и попроси того же Синклера раскритиковать в конкретике.
А ещё лучше — возьми и прочитай все большие старые срачи. Здесь все твои вопросы уже сто раз обсасывались. Меня долго удивляло, что находятся желающие по сто раз одно и то же объяснять — но на своём нынешнем опыте я подозреваю, что это просто со скуки. Когда можно говорить давно известное, не особо напрягая мозги. В любом случае, здесь тебе никто ничего не обязан.
Здравствуйте, Философ, Вы писали:
Ф>Требуется: Ф>Написать консольную программу, по запросу выводящую подходящие покупателю товары. От программы так же требуется возможность определить совместимость компонетов выбранных покупателем. При разработке необходимо учесть, что ассортимент товаров может быть расширен.
Что бы не учитывать то что ассортимент может быть расширен, нужно прежде всего не сужать его.
Для чего тут наследование кроме того что бы было как по букварю? Предполагается различное поведение у товаров? Чем поведение процессора в магазине будет отличаться от материнской платы?
Ф>Здесь я предлагаю написать только классы товаров, т.е. интересуют отношения между классами, их свойства и методы.
Это предложение сделать чью-то работу в обмен на критику? Не заманчиво ни разу.
Здравствуйте, dimgel, Вы писали:
D>Здравствуйте, Философ, Вы писали:
Ф>>Вот так вот оказывается
D>Ага. Возьми сам реши свою задачу, выложи здесь решение и попроси того же Синклера раскритиковать в конкретике. А не напрягай других делать за тебя твою работу в целях твоего образования. Вообще оборзели. Интервьюер хренов.
Я достаточно времени потратил на то, чтобы придумать эту задачу, по крайней мере больше чем требуется для её решения. Автоматизировать магазины не моя работа.
Я внимательно читаю читаю профильные темы, прикладывая мозг к каждому сообщению и "Философия программирования" для меня форум профильный, тщательно формулирую ответы, рассчитывая на такое же отношение от собеседников.
Поэтому отсыл "А мне впадлу тебе отвечать" воспринимаю как оскорбление.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Artifact, Вы писали:
A>Здравствуйте, Философ, Вы писали:
Ф>>Автоматизируем магазин компьютерных комплектующих, который среди прочего торгует следующими видами товаров
A>SQLite подойдёт?
не, мы тут про ООП говорим
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Философ, Вы писали:
Ф>>Требуется: Ф>>Написать консольную программу, по запросу выводящую подходящие покупателю товары. От программы так же требуется возможность определить совместимость компонетов выбранных покупателем. При разработке необходимо учесть, что ассортимент товаров может быть расширен. S>Что бы не учитывать то что ассортимент может быть расширен, нужно прежде всего не сужать его.
S>Для чего тут наследование кроме того что бы было как по букварю? Предполагается различное поведение у товаров? Чем поведение процессора в магазине будет отличаться от материнской платы?
хорошее начало
Ф>>Здесь я предлагаю написать только классы товаров, т.е. интересуют отношения между классами, их свойства и методы. S>Это предложение сделать чью-то работу в обмен на критику?
нет, это я только что сидел выдумывал
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Здравствуйте, samius, Вы писали:
Ф>>>Здесь я предлагаю написать только классы товаров, т.е. интересуют отношения между классами, их свойства и методы. S>>Это предложение сделать чью-то работу в обмен на критику?
Ф>нет, это я только что сидел выдумывал
Зря. Эта задача не оправдывает решения наследованием.
Здравствуйте, Sharov, Вы писали:
S>Поймите, люди работающие в крупных ИТ компаниях не дураки, они прекрасно понимают что C++ 2 закончиться все тем же C++ 1. Здесь как обычно все сводится к компромиссам.
К C++ практически без труда и совершенно без потерь эффективности можно добавить немало как чисто синтаксических, так и семантических расширений, повышающих выразительность и надежность кода. Но почему-то простейшие вещи вроде mutable проникают в стандарт и реализации очень медленно. Такое ощущение, что разработчики крайне консервативны.
Здравствуйте, Философ, Вы писали:
Ф>не, мы тут про ООП говорим
Ну так и я о нём Пытаюсь намекнуть, что пока некоторые пытаются угодать, как оно там через ООП надо по науке то, другие берут ПРАВИЛЬНЫЙ инструмент и решают задачу.
ЗЫ Ну ладно, извините, продолжайте, я больше не вмешиваюсь.
Здравствуйте, Artifact, Вы писали:
A>Здравствуйте, Философ, Вы писали:
Ф>>не, мы тут про ООП говорим
A>Ну так и я о нём Пытаюсь намекнуть, что пока некоторые пытаются угодать, как оно там через ООП надо по науке то, другие берут ПРАВИЛЬНЫЙ инструмент и решают задачу.
A>ЗЫ Ну ладно, извините, продолжайте, я больше не вмешиваюсь.
сорри, глупость сморозил
я просто хорошо себе представляю как эта задача решается с помощью SQL'я
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, velkin, Вы писали:
V>Здравствуйте, Философ, Вы писали:
Ф>>Требуется: Ф>>Написать консольную программу, по запросу выводящую подходящие покупателю товары. От программы так же требуется возможность определить совместимость компонетов выбранных покупателем. При разработке необходимо учесть, что ассортимент товаров может быть расширен.
Ф>>Здесь я предлагаю написать только классы товаров, т.е. интересуют отношения между классами, их свойства и методы.
V>Но это уже не задача, а решение, чего следует избегать. Заранее было решено использовать наследование для распределения данных по классам товаров. А для реальной задачи никто так делать не будет.
Совершенно не обязательно отражать классы товаров в классы ЯП. Просто так сложилось, что видеокарты и винты будут идти в разных разделах прайса и даже лежать на разных стелажах.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Философ, Вы писали:
Ф>>Здравствуйте, samius, Вы писали:
Ф>>>>Здесь я предлагаю написать только классы товаров, т.е. интересуют отношения между классами, их свойства и методы. S>>>Это предложение сделать чью-то работу в обмен на критику?
Ф>>нет, это я только что сидел выдумывал S>Зря. Эта задача не оправдывает решения наследованием.
будет интересно посмотреть на ваше решение
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Здравствуйте, samius, Вы писали:
Ф>будет интересно посмотреть на ваше решение
Мне тоже. Но не настолько, что бы писать его.
Однако, ключевую особенность его (один класс товара без наследования) я готов обсудить. Мне в нем нравится то, что не поменяв ни строчки кода (если представить что оно таки написано), можно добавить товар электромясорубку SATA3 и проверять ее совместимость с конфигурацией клиента. Это ли не возможность расширения?
Здравствуйте, dimgel, Вы писали:
D>Здравствуйте, Философ, Вы писали:
Ф>>>>Я не вижу никакой связи между наследованием и нарушением SRP. D>>>А связь я в первой же строчке своего предыдущего сообщения указал.
Ф>> D>>>А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии. Ф>> Ф>>Это?
D>Нет, вот это: "Просто применение этого принципа как правило даёт кучу простых взаимодействующих объектов, в классах которых наследование реализации почти никогда не требуется."
Запутанные иерархии VS Запутанные взаимодействия
Всё сказанное выше — личное мнение, если не указано обратное.