Re[2]: паранойя наследования
От: Sergey Chadov Россия  
Дата: 07.07.08 17:20
Оценка:
Здравствуйте, WFrag, Вы писали:

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


A>>Добрый день,

A>> я все-таки никак не пойму почему у "профессиональных" разработчиков ПО часто прослеживается паранойя наследования — надо что-то заимплементить, мы пронаследуемся и еще раз и еще.... Может стоит остановиться и подумать над дизайном??? Ведь неоправданное наследование это тупиковый вариант, для последующего внесения изменений, они нарастают как снежный ком...

WF>Да, иной раз смотришь на то, что понаписали джуниоры, и понимаешь, что порой наследование — это как копипаст, но без копипаста


В точку.
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
Re[2]: паранойя наследования
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 08.07.08 05:13
Оценка:
Здравствуйте, жертва мехмата, Вы писали:

[skipped]
ЖМ>Как считает цивилизованная общественность, идея полного отказа от наследования в пользу делегирования — имеет ли право на существование?
Имеет, только это крайне непрактично. Во-первых, если вы бездумно замените вертикальный граф наследования на горизональный граф композиции объектов, система станет абсолютно нечитаемой начинающими программистами. Во-вторых, это, конечно, мизер, да и не столь важно по сравнению с гибкостью системы, тем не менее будет падение производительности системы.
Re[4]: паранойя наследования
От: igna Россия  
Дата: 08.07.08 10:22
Оценка:
Здравствуйте, rsn81, Вы писали:

R>... статически детерминировано;


Это что?

http://en.wikipedia.org/wiki/Statically_indeterminate?
Re[5]: паранойя наследования
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 08.07.08 11:22
Оценка: -1 :)
Здравствуйте, igna, Вы писали:

R>>... статически детерминировано;

I>Это что?
Наследование класса определяется статически на этапе компиляции кода, в отличие от композиции, которая определяется только во время исполнения откомпилированного кода.

I>http://en.wikipedia.org/wiki/Statically_indeterminate?

Очень смешно.
Re[6]: паранойя наследования
От: WFrag США  
Дата: 08.07.08 11:40
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Наследование класса определяется статически на этапе компиляции кода, в отличие от композиции, которая определяется только во время исполнения откомпилированного кода.


В Java по умолчанию все вызовы виртуальные. Разве что при композиции вызов будет скорее всего через интерфейс, что медленнее просто виртуального вызова. Но в обоих случаях Hotspot может соптимизировать виртуальный вызов обычным, если посчитает нужным.
Re[6]: паранойя наследования
От: igna Россия  
Дата: 08.07.08 12:34
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Наследование класса определяется статически на этапе компиляции кода, в отличие от композиции, которая определяется только во время исполнения откомпилированного кода.


Это утверждение и для C++ верно? (Хочу понять, что имеется ввиду.)

Вот композиция:

class A
{
};

class B
{
    A a;
};


Та ли это композиция, "которая определяется только во время исполнения откомпилированного кода"?
Re[7]: паранойя наследования
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.07.08 13:39
Оценка:
Здравствуйте, igna, Вы писали:

I>Та ли это композиция, "которая определяется только во время исполнения откомпилированного кода"?

Надо полагать, имелась в виду динамическая композиция:
class B
{
  A* _a;
  public: B(A* a) { _a = a; }
}

Хотя скорее "полудинамическая":
class B
{
  A& _a;
  public: B(A& a): _a(a){}
}
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: паранойя наследования
От: igna Россия  
Дата: 08.07.08 14:03
Оценка: -1
Здравствуйте, Sinclair, Вы писали:

S>Надо полагать, имелась в виду динамическая композиция:


Надо, больше не остается ничего. Но с тогда этот плюс наследования по сравнению с композицией отпадает. Используй статическую или там "статически детерминированную" композицию, вот и все. Единственный остающийся плюс это то, что наследование "проще в использовании, так как вшито в ООЯ". Тут он прав, наследование "вшили" очень хорошо, и не только в ООЯ.
Re[9]: паранойя наследования
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 09.07.08 03:38
Оценка:
Здравствуйте, igna, Вы писали:

I>Надо, больше не остается ничего. Но с тогда этот плюс наследования по сравнению с композицией отпадает.

Дабы не гадать далее, вы вместо чтения Wiki-заборов откройте уже книгу GoF, а конкретно в главе "Механизмы повторного использования" два параграфа: "Наследование и композиция" и "Сравнение структур времени выполнения и времени компиляции".

I>Используй статическую или там "статически детерминированную" композицию, вот и все.

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

I>Единственный остающийся плюс это то, что наследование "проще в использовании, так как вшито в ООЯ". Тут он прав, наследование "вшили" очень хорошо, и не только в ООЯ.

Попытка №2. Есть две абсолютно (!) различных структуры в ООП:Фишка в том, что за первую структуру обычно отвечает язык (компилятор), а вот за вторую всецело проектировщик (в управляемых платформах компилятор, конечно, пытается и даже некоторые нехорошие вещи, которые могут случится во время исполнения, предсказывает, но все же компиляторы пока до телепатических способностей проектировщиков не доросли) — чем более он опытный, тем более лаконичная структура объектов первого вида, а потому чуть меньше работы компилятору, тем более сложная вторая структура, то есть мозги работают на полную.
Re[10]: паранойя наследования
От: WFrag США  
Дата: 09.07.08 04:20
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Попытка №2. Есть две абсолютно (!) различных структуры в ООП:Фишка в том, что за первую структуру обычно отвечает язык (компилятор), а вот за вторую всецело проектировщик (в управляемых платформах компилятор, конечно, пытается и даже некоторые нехорошие вещи, которые могут случится во время исполнения, предсказывает, но все же компиляторы пока до телепатических способностей проектировщиков не доросли) — чем более он опытный, тем более лаконичная структура объектов первого вида, а потому чуть меньше работы компилятору, тем более сложная вторая структура, то есть мозги работают на полную.


Тут тоже не всё так просто. Очень часто композиция фиксируется однажды (например, IoC контейнером при запуске приложения) и не меняется во время работы.
Re[10]: паранойя наследования
От: igna Россия  
Дата: 09.07.08 04:55
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Наследование класса определяется статически на этапе компиляции кода, в отличие от композиции, которая определяется только во время исполнения откомпилированного кода.


Слово "только" здесь лишнее. Фразу "Object composition is defined dynamically at run-time through objects acquiring references to other objects" (GoF) следует понимать как "Динамически композиция объектов определяется посредством получения ссылок на другие объекты". Что вовсе не означает будто композиция не может определяться статически.
Re[11]: паранойя наследования
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 09.07.08 05:36
Оценка: -3 :)
Здравствуйте, WFrag, Вы писали:

WF>Для той же Java это в общем случае не верно. При компиляции у тебя может быть один SomeSuperClass класс, а при выполнении окажется совсем другой. Более того, он даже по методам/полям может быть местами не совместим.

Совсем не понял, разжуйте.

WF>Тут тоже не всё так просто. Очень часто композиция фиксируется однажды (например, IoC контейнером при запуске приложения) и не меняется во время работы.

Фиксация времени выполнения — это выполнение процессором некоторого набора команд. Фиксация времени компилирования — это фиксация состава этого набора команд. Разницу совсем не видите, да?
Re[11]: паранойя наследования
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 09.07.08 05:36
Оценка: -1 :)
Здравствуйте, igna, Вы писали:

I>Слово "только" здесь лишнее. Фразу "Object composition is defined dynamically at run-time through objects acquiring references to other objects" (GoF) следует понимать как "Динамически композиция объектов определяется посредством получения ссылок на другие объекты". Что вовсе не означает будто композиция не может определяться статически.

Означает. При наследовании время жизни предка и потомка совпадают, соответственно, когда мы уже в контексте обсуждения возможностей потомка (рассматриваем время строго после завершения конструктора) автоматически подразумевается, что родитель тоже существует — это и есть фиксация (есть один объект <=> есть другой объект). А при композиции время жизни объектов не совпадает, в общем случае, в особенности если забыть о GC, вообще никак не связано, а значит, что пока один объект (уже существующий) не получит ссылку на другой объект, он (первый) не может сделать никаких предположений о существовании или нет второго — он попросту не имеет к тому никаких возможностей. Таким образом, говорить здесь какой-то "статической фиксации" является словоблудием.
Re[12]: паранойя наследования
От: igna Россия  
Дата: 09.07.08 05:58
Оценка:
Здравствуйте, rsn81, Вы писали:

R>А при композиции время жизни объектов не совпадает, в общем случае, в особенности если забыть о GC, вообще никак не связано, а значит, что пока один объект (уже существующий) не получит ссылку на другой объект, он (первый) не может сделать никаких предположений о существовании или нет второго — он попросту не имеет к тому никаких возможностей. Таким образом, говорить здесь какой-то "статической фиксации" является словоблудием.


Вот пример:

class A
{
};

class B
{
    A a;
};


Это композиция или нет?
Re[13]: паранойя наследования
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 09.07.08 06:12
Оценка:
Здравствуйте, igna, Вы писали:

[skipped]
I>Это композиция или нет?
Перечитайте определение композиции (особенно внимательно — концовку), которые вы сами же и процитировали здесь: Re[10]: паранойя наследования
Автор: igna
Дата: 09.07.08
— до полного усваивания.
Re[13]: паранойя наследования
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 09.07.08 06:20
Оценка:
Здравствуйте, igna, Вы писали:

[skipped]
I>Это композиция или нет?
Не знаю, быть может, такой беглый пример поможет понять (комменатрии уже все даны, просто пример):
class B: A {
    @Test
    public void test() {
        assert this != null;
    }
}

class C {
    A a;
    
    @Test
    public void test() {
        assert a == null || a != null;
    }
}
Re[14]: паранойя наследования
От: igna Россия  
Дата: 09.07.08 06:43
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Перечитайте определение композиции (особенно внимательно — концовку), которые вы сами же и процитировали здесь: Re[10]: паранойя наследования
Автор: igna
Дата: 09.07.08
— до полного усваивания.


Оно неоднозначно, я же написал, как его следовало правильно перевести.

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

// C++

class A
{
};

class B
{
    A a;
};
Re: паранойя наследования
От: LaptevVV Россия  
Дата: 09.07.08 07:12
Оценка:
Здравствуйте, antonlavreev, Вы писали:

A>Добрый день,

A> я все-таки никак не пойму почему у "профессиональных" разработчиков ПО часто прослеживается паранойя наследования — надо что-то заимплементить, мы пронаследуемся и еще раз и еще.... Может стоит остановиться и подумать над дизайном??? Ведь неоправданное наследование это тупиковый вариант, для последующего внесения изменений, они нарастают как снежный ком...
Ну почему... У меня вот обратная картина: привык мыслить функционально... ОО-решение приходит только во вторую очередь, да и то, хорошенько подумать нужно...
Вот писал интерпретатор виртуальной машины... Сходу написал все на функциях... Основной цикл процессора вызывает нужную функцию по указателю из массива указателей. А код операции является индексом.
А потом только подумал, что можно было определить абстрактный класс Команда и наследоваться от него для реализации каждой команды.
Пока реализовал промежуточное решение: разделил все на 2 дружественных класса: класс-процессор и класс-система команд. Инкапсулировал все функции-команды в класс система-команд как статические. Дальше буду реализовывать нормальный ОО-подход.

Это я опять к топику "что плохого в С++". Сильно много свободы. Одну и ту же работу — в трех разных видах делаю. Правда плюс есть — можно сравнивать подходы на практике. Но это только мне как преподу и пригодиться. А в реальном программировании сравнивать некогда — "копать" надо...
Вот и получается, что в большом проекте каждый пишет как привык, а не так, как нужно...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[14]: паранойя наследования
От: igna Россия  
Дата: 09.07.08 07:52
Оценка: :)
Здравствуйте, rsn81, Вы писали:

R>Не знаю, быть может, такой беглый пример поможет понять


Java к счастью не единственный язык. Возможно в Java наследование и в самом деле имеет тот плюс по сравнению с композицией, что наследование "статически детерминировано", но в других языках "статически детерминированной" может быть и композиция.
Re[12]: паранойя наследования
От: WFrag США  
Дата: 09.07.08 07:55
Оценка:
Здравствуйте, rsn81, Вы писали:

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


WF>>Для той же Java это в общем случае не верно. При компиляции у тебя может быть один SomeSuperClass класс, а при выполнении окажется совсем другой. Более того, он даже по методам/полям может быть местами не совместим.

R>Совсем не понял, разжуйте.

Компилируем такие классы:
public class A {
  public void doSome() {
    System.err.println("A.doSome()");
  }

  public void doSome2() {
    System.err.println("A.doSome2()");
  }
}

// Вызываем один метод если параметров не передано, и другой -- если передано.
public class B extends A {
  public static void main(String[] args) {
    B b = new B();
    b.invoke(args.length == 0);
  }

  public void invoke(boolean flag) {
    if(flag) {
      doSome();
    } else {
      doSome2();
    }
  }
}


Потом в отдельном каталоге компилируем такой класс:
public class A {
  public void doSome() {
    System.err.println("OtherA.doSome()");
  }
}


Копируем туда B.class с первого каталога и запускаем:
wfrag@fragentoo ~/1/2 $ java -cp . B
OtherA.doSome()
wfrag@fragentoo ~/1/2 $ java -cp . B some
Exception in thread "main" java.lang.NoSuchMethodError: B.doSome2()V
    at B.invoke(B.java:11)
    at B.main(B.java:4)


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

WF>>Тут тоже не всё так просто. Очень часто композиция фиксируется однажды (например, IoC контейнером при запуске приложения) и не меняется во время работы.

R>Фиксация времени выполнения — это выполнение процессором некоторого набора команд. Фиксация времени компилирования — это фиксация состава этого набора команд. Разницу совсем не видите, да?

О какой фиксации идёт речь? Что именно фиксируется-то?

В случае Java по большому счету отличие лишь в том, что в случае наследования вызов некоторого функционала делается на параметре this (неявный параметр при вызове методов), а в случае композиции -- на некотором поле (т.е сначала получаем значение поля, потом делаем вызов).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.