Re[4]: Комбинаторный взрыв функциональности благодаря наследованию
От: Abyx Россия  
Дата: 14.12.13 18:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


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

G>>>1) Нету связи между классами и требований соблюдать LSP, там где не требуется полиморфизм.
A>>а чем композиция лучше приватного (множественного) наследования?
S>Очевидно, тем, что она не прибита гвоздями к типу предка.
она гвоздями прибита к типу члена. в чем разница-то?
In Zen We Trust
Re[4]: Комбинаторный взрыв функциональности благодаря наследованию
От: Evgeny.Panasyuk Россия  
Дата: 14.12.13 19:17
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

M>>Именно. Но механиз наследование тут мягко говоря не единственный и совсем не ключевой (хотя смотря в каком языке ХЗ). Может ТС работает с какмнить ЯП где только наследованием мождно делать декомпозицию ?

S>Даже если и так — я по-прежнему не понимаю, каким образом наследование даст нам комбинаторный взрыв функциональности.

Пример с итераторами: есть N контейнеров, к каждому из которых есть итератор, и есть M алгоритмов на итераторах. Каждый алгоритм можно применить к каждому контейнеру, через итераторы — в итоге получается N*M возможных комбинаций, хотя написано всего O(N+M) кода.
Если, например, добавить возможность хранения в контейнерах объектов T разных типов, то получается уже N*M*T разных комбинаций при O(N+M+T) коде.
Это реализуется и через наследование+виртуальные функции, и через шаблоны, и через ФП, и даже в голом C. Это не является какой-то уникальной особенностью ООП.
Re[5]: Комбинаторный взрыв функциональности благодаря наследованию
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.12.13 16:52
Оценка:
Здравствуйте, Abyx, Вы писали:
A>она гвоздями прибита к типу члена. в чем разница-то?
C чего это вы взяли? Правильная композиция — она по ссылке, а не по значению.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Комбинаторный взрыв функциональности благодаря наследованию
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.12.13 16:56
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>Пример с итераторами: есть N контейнеров, к каждому из которых есть итератор, и есть M алгоритмов на итераторах. Каждый алгоритм можно применить к каждому контейнеру, через итераторы — в итоге получается N*M возможных комбинаций, хотя написано всего O(N+M) кода.

EP>Если, например, добавить возможность хранения в контейнерах объектов T разных типов, то получается уже N*M*T разных комбинаций при O(N+M+T) коде.
Это всё понятно. Непонятно, при чём тут наследование. На всякий случай напомню, что ни контейнеры, ни итераторы, ни хранимые типы в STL никакими отношениями наследования не связаны. А там, где связаны (например, в Java), никакого комбинаторного взрыва нет.
EP>Это реализуется и через наследование+виртуальные функции, и через шаблоны, и через ФП, и даже в голом C. Это не является какой-то уникальной особенностью ООП.
Вот как раз жестокий юмор — в том, что реализовывать ваш пример при помощи одного лишь наследования — это просто копец убиться об стену.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Комбинаторный взрыв функциональности благодаря наследованию
От: Evgeny.Panasyuk Россия  
Дата: 15.12.13 18:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это всё понятно. Непонятно, при чём тут наследование. На всякий случай напомню, что ни контейнеры, ни итераторы, ни хранимые типы в STL никакими отношениями наследования не связаны.


В STL не связаны, и я об этом уже говорил выше
Автор: Evgeny.Panasyuk
Дата: 09.12.13
.

S>А там, где связаны (например, в Java), никакого комбинаторного взрыва нет.


Тем не менее подобная концепция реализуется через чистое ООП в виде абстрактных классов и наследование (без шаблонов и дженериков).

EP>>Это реализуется и через наследование+виртуальные функции, и через шаблоны, и через ФП, и даже в голом C. Это не является какой-то уникальной особенностью ООП.

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

Да — там будет больше runtime dispatch'а, да — нужны будут cast'ы, да — наследование делает классы более "закостенелыми".
Но всё равно, всё необходимое что нужно для получения N*M функциональности через O(N+M) код — это полиморфизм, который есть и в ООП.
Другое дело, что это не какая-та уникальная фича наследования — и доступно через другие средства.
Re[6]: Комбинаторный взрыв функциональности благодаря наследованию
От: Jack128  
Дата: 15.12.13 19:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

A>>она гвоздями прибита к типу члена. в чем разница-то?
S>C чего это вы взяли? Правильная композиция — она по ссылке, а не по значению.

в плюсах — тоже не прибита гвоздями. Там можно наследоваться от шаблонного параметра. Другое дело, что при композиции мы можем менять фактический тип объекта в ран-тайм, а в случае шаблонов — только в компил тайм. Но ран-тайм не всегда лучше компил тайма.
Re[7]: Комбинаторный взрыв функциональности благодаря наследованию
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.12.13 03:39
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Тем не менее подобная концепция реализуется через чистое ООП в виде абстрактных классов и наследование (без шаблонов и дженериков).

А также подобная концепция реализуется через ограниченное ООП в виде интерфейсов и классов, без наследования реализации вообще.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Комбинаторный взрыв функциональности благодаря наследованию
От: IT Россия linq2db.com
Дата: 17.12.13 04:00
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Некорректное наследование — это вредно, а корректное — один из самых мощных механизмов в программировании на сегодняшний день.


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

А вообще в программировании на сегодняшний день в плане функциональности самые мощные механизмы перенимаются из функционального программирования. ООП имеет к функциональности отношение лишь как компоновщик, сборщик функциональности в более крупные компоненты, чем просто функции и методы.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Комбинаторный взрыв функциональности благодаря наследованию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.12.13 13:01
Оценка:
Здравствуйте, Abyx, Вы писали:

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


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

G>>1) Нету связи между классами и требований соблюдать LSP, там где не требуется полиморфизм.
A>а чем композиция лучше приватного (множественного) наследования?

Ничем, это практически тоже самое. Даже layout совпадает у классов вида:

class X: private A, private B, private C {}

class Y {
 private:
 A a;
 B b; 
 C c;
}


Только связь при наследовании слишком сильная, это создает проблему хрупкого базового класса.
Re[4]: Комбинаторный взрыв функциональности благодаря наследованию
От: Abyx Россия  
Дата: 17.12.13 13:50
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Ничем, это практически тоже самое. Даже layout совпадает у классов вида:


G>
G>class X: private A, private B, private C {}

G>class Y {
G> private:
G> A a;
G> B b; 
G> C c;
G>}
G>


G>Только связь при наследовании слишком сильная, это создает проблему хрупкого базового класса.


чем связь с приватным базовым классом сильнее связи с приватным членом?
чем хрупкий базовый класс отличается от хрупкого члена?
чем this.foo() отличаеся от m_a.foo() ?
In Zen We Trust
Re[5]: Комбинаторный взрыв функциональности благодаря наследованию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.12.13 14:07
Оценка:
Здравствуйте, Abyx, Вы писали:

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


G>>Ничем, это практически тоже самое. Даже layout совпадает у классов вида:


G>>
G>>class X: private A, private B, private C {}

G>>class Y {
G>> private:
G>> A a;
G>> B b; 
G>> C c;
G>>}
G>>


G>>Только связь при наследовании слишком сильная, это создает проблему хрупкого базового класса.


A>чем связь с приватным базовым классом сильнее связи с приватным членом?

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


A>чем хрупкий базовый класс отличается от хрупкого члена?

Хрупкий член это наверное половая болезнь...

A>чем this.foo() отличаеся от m_a.foo() ?

Тем что за m_a при желании может стоять любая реализация, а this.foo() привязывается по время компиляции.

Пример простой:
Был Класс MyController, который использовал MyService. Этот же MyService был использован в 10 других классах.
Потом появился NewMyService: MyService, который используется в NewMyController:MyController. А потом от наследника NewMyController отказались и начали подсовывать нужную реализацию через IoC.

Если бы в схеме использовалось наследование, то ничего хорошего бы не вышло.
Re[6]: Комбинаторный взрыв функциональности благодаря наследованию
От: Abyx Россия  
Дата: 17.12.13 15:19
Оценка:
Здравствуйте, gandjustas, Вы писали:

A>>чем связь с приватным базовым классом сильнее связи с приватным членом?

G>Ну например нельзя просто так взять добавить метод в базовый класс.

почему нельзя?


 struct Base {
    void a() { printf("a"); }
+   void b() { printf("b"); }
 };

 struct Some : private Base {
    void do_a() { this->a(); }
 };


взял и добавил новый метод b. никто ничего и не заметил.

A>>чем this.foo() отличаеся от m_a.foo() ?

G>Тем что за m_a при желании может стоять любая реализация,
а может и не любая. в С++ у "A a;" вполне конкретная реализация, а не "любая".
G>а this.foo() привязывается по время компиляции.

G>Пример простой:

G>Был Класс MyController, который использовал MyService. Этот же MyService был использован в 10 других классах.
G>Потом появился NewMyService: MyService, который используется в NewMyController:MyController. А потом от наследника NewMyController отказались и начали подсовывать нужную реализацию через IoC.
G>Если бы в схеме использовалось наследование, то ничего хорошего бы не вышло.

т.е. с наследованием было бы в начале

class MyController : public AbstractController, private MyService {};
class MyController1 : private MyService {};
...
class MyController10 : private MyService {};


а потом сделали бы
class NewMyController : public AbstractController, private NewMyService {};


и в чем проблема? и зачем IoC?
In Zen We Trust
Re: Комбинаторный взрыв функциональности благодаря наследованию
От: Pzz Россия https://github.com/alexpevzner
Дата: 17.12.13 15:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Понятна ли вам мысль, и если да, то согласны ли вы с ней, что основное преимущество наследования заключается в том, что при адекватном применении в сочетании с полиморфизмом оно дает комбинаторный взрыв функциональности, то есть добавление новых классов и объектов дает непропорционально большой прирост общей функциональности иерархии классов?


Нет, в этом заключается ее основной недостаток.

Новая функциональнисть из ничего не возникнет. Новая функциональность — это когда программа делает что-то новое и полезное. Новое и полезное за вас никто автоматически не нагенерирует. А вот хаос, он в "умелых" руках действительно возрастает в геометрической прогрессии.
Re[7]: Комбинаторный взрыв функциональности благодаря наследованию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.12.13 18:34
Оценка:
Здравствуйте, Abyx, Вы писали:

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


A>>>чем связь с приватным базовым классом сильнее связи с приватным членом?

G>>Ну например нельзя просто так взять добавить метод в базовый класс.

A>почему нельзя?



A>
A> struct Base {
A>    void a() { printf("a"); }
A>+   void b() { printf("b"); }
A> };

A> struct Some : private Base {
A>    void do_a() { this->a(); }
A> };
A>


A>взял и добавил новый метод b. никто ничего и не заметил.


А если уже есть метод b в Some?
А если класс Some является предком класса Some1 и Base тоже является?


A>>>чем this.foo() отличаеся от m_a.foo() ?

G>>Тем что за m_a при желании может стоять любая реализация,
A>а может и не любая. в С++ у "A a;" вполне конкретная реализация, а не "любая".
Это детали конкретного синтаксиса конкретного языка.


G>>Пример простой:

G>>Был Класс MyController, который использовал MyService. Этот же MyService был использован в 10 других классах.
G>>Потом появился NewMyService: MyService, который используется в NewMyController:MyController. А потом от наследника NewMyController отказались и начали подсовывать нужную реализацию через IoC.
G>>Если бы в схеме использовалось наследование, то ничего хорошего бы не вышло.

A>т.е. с наследованием было бы в начале


A>
A>class MyController : public AbstractController, private MyService {};
A>class MyController1 : private MyService {};
A>...
A>class MyController10 : private MyService {};
A>


A>а потом сделали бы

A>
A>class NewMyController : public AbstractController, private NewMyService {};
A>


A>и в чем проблема? и зачем IoC?


Проблема в том, что NewMyController должен быть унаследован от MyController, фактически он и отличается только ссылкой на MyService.
Re: Комбинаторный взрыв функциональности благодаря наследованию
От: Mr.Delphist  
Дата: 29.01.14 16:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Некорректное наследование — это вредно, а корректное — один из самых мощных механизмов в программировании на сегодняшний день.


Корректное наследование, дополненное корректным агрегированием вместо некорректного наследования, даёт мощнейшую основу для написания корректных программ
(чего-то я капитанствую, да)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.