Re[10]: Так все-таки, что же не так с ООП?
От: Философ Ад http://vk.com/id10256428
Дата: 01.02.12 15:38
Оценка:
Здравствуйте, 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>а все что не по делу усложняет программу является антипаттерном.


Не согласен. Я вообще не знаю что такое антипаттерн. Если под словом паттерн понимать название общепринятого способа решать задачу (или способ решения, без имени), то антипаттерн — общепринятое отрицательное мнение о способе решения задачи.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[3]: Главная проблема все же в ООПе
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 01.02.12 17:41
Оценка: +2
Здравствуйте, hardcase, Вы писали:

H>К слову, мультиметоды в C# можно эмулировать с помощью dynamic-а.


За эмуляцию с потерей статического контроля типов без явной на это нужды надо от профессии отлучать
... << RSDN@Home 1.2.0 alpha 5 rev. 16 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[3]: Так все-таки, что же не так с ООП?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.12 05:02
Оценка:
Здравствуйте, Философ, Вы писали:
Ф>Да, ООП здесь можно заменить на что угодно.
Ф>Незрелая область деятельности, авторы "учебников" выдают субъективное мнение за истину, хотя и пишут не о сути мироздания, а об интсрументах и способах решения задач, преподносят своё понимание хорошего и плохого.
Да вроде бы не то, чтобы незрелая. Просто городские легенды кочуют из одного учебника в другой. Все эти объекты "автомобиль" с наследниками "грузовой автомобиль" — полная ерунда, которая учит вредным идеям.

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>>В итоге мы имеем разрыв между тем, чему учат в учебниках и тем, что стоит применять на практике. Отсюда и весь этот горький катаклизм, который мы наблюдаем.


Ф>А наблюдаем мы на практике то, что было когда-то в учебнике

Не, на практике мы наблюдаем результаты неудачных попыток применять учебные примеры, разбившихся о рифы суровой реальности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Так все-таки, что же не так с ООП?
От: Философ Ад http://vk.com/id10256428
Дата: 02.02.12 08:18
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Философ, Вы писали:


S>>>Редкий частный случай, когда имеет смысл наследовать реализацию, а не интерфейс, выдаётся за основное применение.

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

С утверждением "смысл наследовать реализацию — редкий частный случай". Отнюдь не редкий.

Ф>>Пример: представим класс A, для которого планируется сделать торчу наследников

S>Не вижу примера. Вижу применение паттерна "шаблонный метод"

Посмотрел описание паттерна. Да это именно он и есть

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


Виноват.
Попробую исправится.
Собственно паттерн "шаблонный метод" был мною найден случайно, в процессе попыток упросить код и уменьшить дублирование. О паттернах проектирования я тогда только слышал.
!) Предпосылки:


interface IA
{
void PublicMethod1 ();
}


Классов, реализующих этот интерфейс планировалось великое множество, и было кое-что, что их объединяло:
а) одинаковые приватные поля
б) одинаковые реализации некоторых (!) приватных приватных методов
в) одинаковая реализация публичного метода

Иллюстрация:
  Скрытый текст
//Реализация метода Method2() в этих классах отличается, 
//но в рамках решаемой задачи присутствует он во всех классах с интерфейсом IA

class 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>Вы же хотели повторного использования?


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

//Сорри, осилил не всё.
//Чуть позже продолжу.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[11]: Так все-таки, что же не так с ООП?
От: igna Россия  
Дата: 02.02.12 08:39
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Данные по прежнему остались в абстрактном классе A, из него вынесли один protected метод из N...


Так данные-то тоже вынести надо. В класс имплементирующий интерфейс.
Re[12]: Так все-таки, что же не так с ООП?
От: Философ Ад http://vk.com/id10256428
Дата: 02.02.12 08:43
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Философ, Вы писали:


Ф>>Данные по прежнему остались в абстрактном классе A, из него вынесли один protected метод из N...


I>Так данные-то тоже вынести надо. В класс имплементирующий интерфейс.


я ничего не понимаю.

код в студию

заодно взляните вот на этот пост
http://www.rsdn.ru/forum/philosophy/4600189.1.aspx
Автор: Философ
Дата: 02.02.12
Всё сказанное выше — личное мнение, если не указано обратное.
Re[2]: Страуструп и Гослинг
От: igna Россия  
Дата: 02.02.12 08:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

...
S>Очень мало литературы упирает на поведение в поисках иерархий наследования, и много — на состояние. Редкий частный случай, когда имеет смысл наследовать реализацию, а не интерфейс, выдаётся за основное применение.

"Абсурд" этот ни в какую литературу по ООП не проник, он в ней был с самого начала, по крайней мере со времени популяризации C++. Не надо теперь делать вид, будто все было бы хорошо, если бы не некие абсурдописатели, иначе к последним нужно отнести самого Страуструпа, унаследовал же он Circle от Shape на первых же страницах своей The C++ Programming Language. Далее, Гослинг при разработке Java выкинул множественное наследование, но оставил наследование реализации очевидно отнюдь не считая последнее "редким частным случаем".
Re[3]: Страуструп и Гослинг
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.12 09:02
Оценка:
Здравствуйте, igna, Вы писали:

I>"Абсурд" этот ни в какую литературу по ООП не проник, он в ней был с самого начала, по крайней мере со времени популяризации C++. Не надо теперь делать вид, будто все было бы хорошо, если бы не некие абсурдописатели, иначе к последним нужно отнести самого Страуструпа, унаследовал же он Circle от Shape на первых же страницах своей The C++ Programming Language.

Я не понял. Вы с кем не согласны — со мной или со Страуструпом?
Вы что, серъёзно полагаете, что наследование Circle от Shape — хорошая, годная идея, которая может реально применяться в какой-то программе?

I>Далее, Гослинг при разработке Java выкинул множественное наследование, но оставил наследование реализации очевидно отнюдь не считая последнее "редким частным случаем".

Хм. То есть вы полагаете, что из наличия наследования реализации в Java прямо следует то, что Гослинг не считал его редким частным случаем?
Очень интересно. Расскажите мне тогда, как он должен был поступить, если бы всё-таки считал его редким, но важным частным случаем.

И заодно расскажите, какие выводы мы можем сделать про различие подходов Гослинга и Страуструпа к различным видам наследования из наличия в Java интерфейсов и отсутствия оных в C++.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Так все-таки, что же не так с ООП?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.12 09:11
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>С утверждением "смысл наследовать реализацию — редкий частный случай". Отнюдь не редкий.



Ф>
Ф>interface IA
Ф>{
Ф>void PublicMethod1 ();
Ф>}
Ф>


Ф>Классов, реализующих этот интерфейс планировалось великое множество, и было кое-что, что их объединяло:

Ф>а) одинаковые приватные поля
Ф>б) одинаковые реализации некоторых (!) приватных приватных методов
Ф>в) одинаковая реализация публичного метода
Пока непонятно даже, что вас подвигло на порождение этого вашего интерфейса, т.е. чем вас не устроил делегат Action в качестве такого "интерфейса".
Ф>Таким образом интерфейс был заменён на абстрактный класс.
По-прежнему непонятно, чем именно отличались все эти множественные классы, у которых одинаковые приватные члены.

Ф>Наследование здесь позволило убрать дублирование кода.

Какой именно код у вас дублировался?

Я тут уже давал ссылку на пример с TextReader.
Вот там наследование реализации уместно, т.к. наследник может выбирать, сколько методов перекрывать. Перекрыв метод побайтного чтения Read можно сразу получить работающую реализацию. Перекрытие методов ReadLine и ReadAlllines позволяет улучшить производительность наивного решения, если она не устраивает. При этом наследоваться от конкретного TextReader если хочется всего лишь немножко подправить его поведение категорически не надо — надо агрегироваться.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Так все-таки, что же не так с ООП?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.02.12 09:15
Оценка: 1 (1)
Здравствуйте, Философ, Вы писали:
Ф>код в студию
Я же вам привёл код. Вот вариант, предлагаемый igna:
public static int PublicMethod1(this IA a)
{
  //...
  if (a.MyMethod1())..
  //....
}

MyMethod1 вынесен в интерфейс, интерфейс передаётся в качестве параметра a в метод PublicMethod1.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Страуструп и Гослинг
От: igna Россия  
Дата: 02.02.12 09:40
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>Я не понял. Вы с кем не согласны — со мной или со Страуструпом?


С обоими.

1. ООП, в том виде в котором его популяризировали, вещь вредная.
2. Утверждать теперь, что это, мол, и не ООП вовсе было, а так, заблуждение, а настоящее ООП вот оно, большое, розовое и пушистое; можно конечно, но на мой взгляд неприлично.

S>Вы что, серъёзно полагаете, что наследование Circle от Shape — хорошая, годная идея, которая может реально применяться в какой-то программе?


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

S>Очень интересно. Расскажите мне тогда, как он должен был поступить, если бы всё-таки считал его редким, но важным частным случаем.


Скорее всего выбросил бы как выбросил множественное наследование. Тоже ведь "редкий, но важный частный случай".
Re[6]: Так все-таки, что же не так с ООП?
От: Философ Ад http://vk.com/id10256428
Дата: 02.02.12 11:51
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Философ, Вы писали:


Ф>>С утверждением "смысл наследовать реализацию — редкий частный случай". Отнюдь не редкий.

S>

Ф>>
Ф>>interface IA
Ф>>{
Ф>>void PublicMethod1 ();
Ф>>}
Ф>>


Ф>>Классов, реализующих этот интерфейс планировалось великое множество, и было кое-что, что их объединяло:

Ф>>а) одинаковые приватные поля
Ф>>б) одинаковые реализации некоторых (!) приватных приватных методов
Ф>>в) одинаковая реализация публичного метода
S>Пока непонятно даже, что вас подвигло на порождение этого вашего интерфейса, т.е. чем вас не устроил делегат Action в качестве такого "интерфейса".

Это стёб чтоль?
Считаете ли вы меня придурком?
Всё сказанное выше — личное мнение, если не указано обратное.
Re[7]: Так все-таки, что же не так с ООП?
От: dimgel Россия https://github.com/dimgel
Дата: 02.02.12 12:02
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Это стёб чтоль?

Ф>Считаете ли вы меня придурком?

Гыгы. В общем, ИМХО твои оппоненты просто забыли произнести слово "SRP". Но вообще, правильное решение будет зависеть от конкретной ситуации. В большинстве случаев делегат лучше, а единственный более-менее часто испольуемый паттерн, когда рулит наследование, совсем недавно вот тут неподалёку
Автор: Qbit86
Дата: 26.01.12
обсуждали.
Re[8]: Так все-таки, что же не так с ООП?
От: Философ Ад http://vk.com/id10256428
Дата: 02.02.12 12:09
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, Философ, Вы писали:


Ф>>Это стёб чтоль?

Ф>>Считаете ли вы меня придурком?

D>Гыгы. В общем, ИМХО твои оппоненты просто забыли произнести слово "SRP".


что не так здесь с SRP?
Всё сказанное выше — личное мнение, если не указано обратное.
Re[9]: Так все-таки, что же не так с ООП?
От: dimgel Россия https://github.com/dimgel
Дата: 02.02.12 12:21
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>что не так здесь с SRP?


С SRP всё хорошо, спасибо. Просто применение этого принципа как правило даёт кучу простых взаимодействующих объектов, в классах которых наследование реализации почти никогда не требуется. А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии. Самый часто встречающийся в моей практике пример — когда вместо того, чтобы вынести некий повторно используемый код в какой-нибудь отдельный Util, делают общий базовый класс для совершенно разнородных вещей и забабахивают этот повторно используемый код в protected-метод базового класса. Вот до отвращения уже достали это говно рефакторить, ей богу.
Re[10]: Так все-таки, что же не так с ООП?
От: dimgel Россия https://github.com/dimgel
Дата: 02.02.12 12:23
Оценка:
D>вместо того, чтобы вынести некий повторно используемый код в какой-нибудь отдельный Utilсервис
Re[10]: Так все-таки, что же не так с ООП?
От: Философ Ад http://vk.com/id10256428
Дата: 02.02.12 12:49
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, Философ, Вы писали:


Ф>>что не так здесь с SRP?


D>С SRP всё хорошо, спасибо. Просто применение этого принципа как правило даёт кучу простых взаимодействующих объектов, в классах которых наследование реализации почти никогда не требуется.

D>А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии. Самый часто встречающийся в моей практике пример — когда вместо того, чтобы вынести некий повторно используемый код в какой-нибудь отдельный Util, делают общий базовый класс для совершенно разнородных вещей и забабахивают этот повторно используемый код в protected-метод базового класса. Вот до отвращения уже достали это говно рефакторить, ей богу.

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

SRP хотя и формулировался для ООП вполне применим за его пределами
Всё сказанное выше — личное мнение, если не указано обратное.
Re[11]: Так все-таки, что же не так с ООП?
От: dimgel Россия https://github.com/dimgel
Дата: 02.02.12 13:02
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Я не вижу никакой связи между наследованием и нарушением SRP. Люди склонные к этому, прекрасно справляются и без наследования, и даже без ООП


Это понятно. "Все языки полны по Тьюрингу, поэтому на любом языке можно написать ужасный код." ~(c) VladD2. Но здесь обсуждалось, как надо лучше, а не хуже. А связь я в первой же строчке своего предыдущего сообщения указал.
Re[12]: Так все-таки, что же не так с ООП?
От: Философ Ад http://vk.com/id10256428
Дата: 02.02.12 13:20
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, Философ, Вы писали:


Ф>>Я не вижу никакой связи между наследованием и нарушением SRP.


D>А связь я в первой же строчке своего предыдущего сообщения указал.



D>А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии.


Это?
Вы мне мозг взрываете. Какое к чёрту "предпочтение"? Мы тут чем занимаемся поставленную задачу своим кодом решаем, или картину маслом пишем? Если второе, то я предпочитаю сочетание зелёного с ультрамарином.

Если же мы пишем код, то для класса не нарушающего SRP, одинаковые действия для всей иерархии, в рамках решаемой задачи, будут выделены в неприватные методы. Бывает, конечно совсем тяп-ляп: никаких отдельных методов создано не будет, а решение построено с помощью старинной китайской технологии "Copy-paste".
Всё сказанное выше — личное мнение, если не указано обратное.
Re[13]: Так все-таки, что же не так с ООП?
От: dimgel Россия https://github.com/dimgel
Дата: 02.02.12 12:33
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>>>Я не вижу никакой связи между наследованием и нарушением SRP.

D>>А связь я в первой же строчке своего предыдущего сообщения указал.

Ф>

D>>А предпочтение наследования как правило приводит к злоупотреблению им, что на выходе даёт запутанные иерархии.
Ф>

Ф>Это?

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

Ф>Вы мне мозг взрываете. Какое к чёрту "предпочтение"?


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