Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » В чем преимущество ООП ?

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10

Открыть новую тему     Написать ответ в эту тему

druff

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
wasilissk
Какими именно концепциями? RAD?

Всего записей: 402 | Зарегистр. 14-11-2006 | Отправлено: 10:01 07-10-2011
wasilissk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
druff
Визуальное программирование, подход к реализации ООП (напр. множественное наследование, наследование интерфейсов, виртуальные конструкторы), типизация (о чем говорил Qraizer здесь http://forum.ru-board.com/topic.cgi?forum=33&topic=4312&start=100#3).

Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 13:37 07-10-2011
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
wasilissk

Цитата:
Синтаксисом?

Очевидно имелся ввиду не синтаксис. Вы наверно что-то подразумевали под общим между C и С#, но это не концепция. Какой параметр называется концепцией? Думаю неплохо ориентируюсь в C# и Delphi.
 
Добавлено:

Цитата:
множественное наследование

Это концепция Delphi?

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 17:20 08-10-2011
wasilissk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delover
Э-э-э, никак не мог догнать, чего вы от меня хотите.
Прочитал еще раз сообщение.

Цитата:
А мне кажется что Сишарп больше похож на Си. Как ни странно это звучит, это так. )

Так вы имели в виду именно C, а не С++? Мое сообщение вообще-то относилось именно к отличиям С++ от C#. В любом случае у С и C# еще меньше общего... Точнее вообще ничего общего, кроме синтаксиса, нет.

Цитата:
Это концепция Delphi?

Это одна из концепций ООП, которая применяется в C++ и от которой отказались в C# и Delphi.

Цитата:
Очевидно имелся ввиду не синтаксис.

А что тогда?

Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 21:09 08-10-2011 | Исправлено: wasilissk, 21:10 08-10-2011
Qraizer



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Концепции ссылочных типов, как я понимаю.

----------
Одни с годами умнеют, другие становятся старше.

Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 23:43 08-10-2011
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
wasilissk
Тогда, значит, Вы не поняли моё сообщение, а я Ваше. )))

Цитата:
Точнее вообще ничего общего, кроме синтаксиса, нет.  

Ну это пустяки конечно. Язык влияет только на мышление.
 
В С# отказались видеть различие между интерфейсом и объектом, предполагаю из экономии, а не из-за Паскаля. В Delphi отказались от множественного, но не от агрегации. Помнится в Си (слабо различаю C++ и C) оконные ресурсы писали текстом и линковали в ресурс, либо вставляли в код. Чем дизайнер сишарпа похож на TFiler дельфи остаётся загадкой. Что же похожего на Дельфи объясните плиз. Пока не понял, но уже весело.
 

Цитата:
Концепции ссылочных типов, как я понимаю.

В общем конечно отсутствуют двухбайтовые ссылки и различные типы моделей памяти, как в Си, надо полагать сишарп пострадал, что в нём нет ссылок?

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 03:17 09-10-2011 | Исправлено: delover, 04:32 09-10-2011
wasilissk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
В С# отказались видеть различие между интерфейсом и объектом

В C# как и в Delphi совершенно определенные различия объекта от интерфейса, в отличие от С++.  

Цитата:
В Delphi отказались от множественного, но не от агрегации.

И-и-и?..

Цитата:
Помнится в Си (слабо различаю C++ и C) оконные ресурсы писали текстом и линковали в ресурс, либо вставляли в код.  

Гораздо проще все делать в предназначенном для этого редакторе ресурсов, но не суть.  

Цитата:
Чем дизайнер сишарпа похож на TFiler дельфи остаётся загадкой. Пока не понял, но уже весело.

Куда уж веселее. Презабавный факт, наличие встроенных визуальных редакторов, заточенность проектирования от визуального представления, свое видение MVC это все ничего не значащий факт. А вот тонкости в реализации RTTI это умотаться какая важная вещь - концепция никак.
Кстати, как там насчет чего-то общего у С и C# помимо синтаксиса?

Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 15:46 09-10-2011
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
wasilissk


Цитата:
В C# как и в Delphi совершенно определенные различия объекта от интерфейса

В C# какие? Может скажу глупость но интерфейс это таблица методов с счётчиком ссылок, вроде бы. В фреймворке, по моим представлениям - всё является объектами (у которых те же счётчики для коллекции). С тысячного взгляда различия сложно заметить. Ну а то что в C++ вы их можете не замечать, так попробуйте запустить Вижуал Бэйсик. А может С++ на Бейсик похож больше?
 

Цитата:
>В Delphi отказались от множественного, но не от агрегации.  
И-и-и?..

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

Цитата:
Гораздо проще все делать в предназначенном для этого редакторе

Разумеется проще, запускаем WorkShop и вуаля (угу не суть).
 

Цитата:
А вот тонкости в реализации RTTI

По моему Вы о них говорите первым, не знаю это понятие, что-то похожее на Member. )
 

Цитата:
заточенность проектирования от визуального представления, свое видение MVC это все ничего не значащий факт.

Угу, это проигрышный момент Визуал Студии. Как это так с визуальным дизайном и не на голом апи.
 

Цитата:
Кстати, как там насчет чего-то общего у С и C# помимо синтаксиса?

Ну перечитайте вдумчиво что написано было.  
http:||ru.wikipedia.org/wiki/Model-View-Controller
Ничего не понял.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 20:39 09-10-2011 | Исправлено: delover, 21:04 09-10-2011
wasilissk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Может скажу глупость но интерфейс это таблица методов с счётчиком ссылок, вроде бы

Глупость. Интерфейс это именованный набор сигнатур методов и ничего более. Счетчик ссылок никого отношения к интерфейсу не имеет. У интерфейса не может быть данных.

Цитата:
В фреймворке, по моим представлениям - всё является объектами

Еще одна глупость.  

Цитата:
Ну а то что в C++ вы их можете не замечать, так попробуйте запустить Вижуал Бэйсик. А может С++ на Бейсик похож больше?

Переформулируйте, пока что - третья глупость.

Цитата:
Начинаю сомневаться, что стоит продолжать

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

Цитата:
следствие агрегации множественное наследование, немного отличающееся по синтаксису

Множественное наследование – концепция в ООП, основывающаяся на отношении наследования - “является is a”. Агрегирование – отношение “иметь has a”. Агрегирование не является множественным наследованием, ни в смысле объектно-ориентированного проектирования, ни на низком уровне реализации компилятором. Посредствам отношения агрегирования можно создать альтернативу множественному наследованию, что и было сделано в языках C# и Delphi.  

Цитата:
По моему Вы о них говорите первым

Неужели? Про TFiler я первым сказал?  

Цитата:
Ну перечитайте вдумчиво что написано было.

Где читать? Процитируйте, будьте милостивы.

Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 22:19 09-10-2011
Qraizer



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
...надо полагать сишарп пострадал, что в нём нет ссылок?
delover, нет. Он пострадал тем, что нет единой семантики для всех типов. В C++ все типы нессылочные, и есть отдельный тип - ссылка на что-либо. Упрощённо говоря, любой тип можно сделать ссылочным по требованию дизайна.
Дело не в том, что ссылочные типы - зло. В Питоне всё наоброт - все типы ссылочные, и это тоже нормально. Ненормально - когда половина так, половина эдак. Когда я пишу
Код:
template <typename T>
T add(T x, T y)
{
  x += y;
  return x;
}
я уверен, что любой вызов add() с любым T не приведёт к изменению аргументов, потому что код будет работать с копиями, и вернёт тоже копию. Давай посмотрим на два вызова:
Код:
class Complex;
/* ... */
int a1, b1;
Complex a2, b2;
 
/* ... */
 
b1 = add(a1, a1);
b2 = add(a2, a2);
Представь, что это на Дельфи. Весело? И как тут быть? С другой стороны такой прототип
Код:
template <typename T>
T add(T& x, const T& y)
даст мне всю необходимую информацию.
Настоящая обобщённость не просто параметризирует типы. Она действительно абстрагируется от типов вообще и позволяет писать код и структуры данных, базируясь не на типах, а их свойствах. И эти свойства могут быть однозначно задекларированы интерфейсом, а не реализацией. В том же Питоне опять же единая семантика типов делает управление данными в обобщённом коде так же однозначными. Да, пришлось бы для получения копий значений, а не ссылок, использовать специальные языковые конструкции, и это была бы деталь реализации, а не интерфейса, в сожалению. Поэтому подобное поведение приходится документировать в мануалах. И поэтому же я считаю, что нессылочные по дефолту типы, как в C++, выгоднее, нежели ссылочные по дефолту, как в Питоне.
И тем не менее Питон остаётся гораздо более удобным по сравнению с дженериками C#, Джавы или Дельфи, где полный бардак с обощённостью. Нету там обобщённости, там просто типовая параметризация с весьма ограниченными, если не желаем сюрпризов, возможностями. Получается, что с дженериками я должен как-то узнать свойство ссылочности и поступить то ли так, то ли эдак. Т.е. поветвиться в ран-тайм. И это для языков со статической типизацией. Бред. Ирония в том, что такая же задача в C++ решается в компайл-тайм, хотя ему-то она как раз не задача.
 
Добавлено:
wasilissk, на предмет отсутствия множественного наследования реализаций в C# сказать не могу. Но касательно Дельфи - её там не может быть в связи с самой моделью ООП. То, что с ООП сделали в Дельфи безусловно приятно для многих, но лично мною такая модель воспринимается негативно главным образом из-за невозможности уйти от высокой её стоимости. В частности строить в ней множественное наследование реализаций было просто опасно из-за совсем уж диких неопределённостей и сложностей проектирования взаимоотношений виртуальных методов вкупе с их вызовами из конструкторов объектов.

----------
Одни с годами умнеют, другие становятся старше.

Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 02:25 10-10-2011
wasilissk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Qraizer

Цитата:
В частности строить в ней множественное наследование реализаций было просто опасно из-за совсем уж диких неопределённостей и сложностей проектирования взаимоотношений виртуальных методов

О каких сложностях взаимоотношений виртуальных методов идет речь?
В целом же, все как раз наоборот, в Delphi от множественного наследования отказались в силу его, мягко говоря, сомнительной необходимости, при совершенно явных недостатках. А вот в частности этот отказ позволил реализовать множество других сомнительных возможностей, типа виртуальных конструкторов.

Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 07:54 10-10-2011
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Представь, что это на Дельфи.

) Да, представляю. Например в PHP все данные изначально строки (по дефолту), и вполне себе преобразуются в строки, если это не массив. Так же как в Си, можно написать "x .= y". Но это просто к слову. В Сишарп единым правилом можно назвать то что все типы - объекты. Взлянув в дизасемблер:

Код:
 
 int i = 3;  object o = (object)i; byte b = (byte)i;
//              box                          conv - похоже на конвертацию
 

Возможно инструкция box похожа на конвертацию, но мне думается что это инструкция разрешающая доступ к инту как к объекту. Тут могу ошибаться, но если взять за принцип то что всё объекты, ошибок не будет. Удивляет скорость с какой Сишарп подхватывает редактируемые данные. Без разницы объявлен объект до использования или после. Вобщем скорость возможно от паскаля, а вот свобода всёже от Си.  
Добавлю, так же как и в Си, в Сишарп нужно прочитать очень много умных книжек. Тогда получится настоящее приложение. Ну и удовольствие от полученного.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 12:41 10-10-2011 | Исправлено: delover, 15:35 10-10-2011
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Эмм.  
Тогда стоит продолжить. Появляется, значит, у разработчика Дельфи время поработать в Сишарп. За годы работы глаза его стали видеть хуже и некоторое время в Сишарпе он видит только Дельфи. Хотя приложение не выходит, его глаза начинают привыкать и потихоньку возникает момент узнавания. Да, вот это, вот так вот должно быть в Си. И в этот момент приложение начинает получаться. Возможно от радости, а возможно из-за вполне здравых предпосылок он говорит - Сишарп больше похож на Си (для него он стал более похож на Си и всё стало получаться). Знал ли он тогда, что если бы он хотел в глазах девочек выглядеть знатоком Си, то понимал бы - надо говорить Сишарп не похож на Си? Наверно не знал. Да в точно таких чуствах - радости, что кое чего получилось был добавлен пост про схожести.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 18:27 10-10-2011
Qraizer



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
В целом же, все как раз наоборот, в Delphi от множественного наследования отказались в силу его, мягко говоря, сомнительной необходимости, при совершенно явных недостатках.
wasilissk, по поводу сомнительной необходимости - это известный пропагандистическоий силлогизм поставщиков ООП-моделей, не предоставляющих множественное наследование реализаций.
    Внимание, два вопроса:
  1. если необходимость сомнительна, почему оставили множественное наследование интерфейсов?
  2. если мой класс реализует интерфейс, вопроса нет, но если он не реализует, а является одной из уже готовых реализаций, почему он не может прямо это сделать, а должен костылить в сторону агрегации, оставив интерфейс в у себя в предках?
По поводу последнего. Мало того, что это получается враньём. Если я наследуюсь от интерфейса, я им якобы являюсь, но по факту я являюсь не интерфейсом, а всего лишь одной из всех возможных его реализаций. Помимо этого, как ты абсолютно верно заметил, агрегация определяет совсем не то отношение между классами, что и наследование. Почему считается нормальным использовать иные отношения интерфейсов по сравнению с отношениями реализаций? IA и IB - наследуются, а SomeA и SomeB, реализующие эти IA и IB, агрегируются. Любой грамотный ОО-архитектор назовёт это бредом и согласится с таким дизайном только как с  вынужденной мерой. Почему бы просто не унаследоваться от SomeA и SomeB? Всё показано правильно, и никто никому не врёт.
Что касается явных недостатков... ладно, просто приведи аргументы. Хотя бы один пример недостатка.

Цитата:
А вот в частности этот отказ позволил реализовать множество других сомнительных  возможностей, типа виртуальных конструкторов.
Возможности именно что сомнительны. Я только не понял, ты соглашается или споришь? Если споришь, я могу продолжить свою мысть фактами.
 
P.S. Я никогда не холиварю без фактов, но и ожидаю аналогичного от оппонентов.

----------
Одни с годами умнеют, другие становятся старше.

Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 00:36 11-10-2011
wasilissk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Qraizer

Цитата:
если необходимость сомнительна, почему оставили множественное наследование интерфейсов?  

Не оставили, а предпочли. Разумеется потому, что часто возникает необходимость унаследовать поведение двух сущностей. Полная же реализация множественного наследования как is a является излишней.

Цитата:
если мой класс реализует интерфейс, вопроса нет, но если он не реализует, а является одной из уже готовых реализаций

Этого не осилил. Что есть готовая реализация в терминах программерского языка? Замечу только, что, во-первых, наследование реализации и наследование интерфейса в Delphi суть совершенно различные операции, во-вторых, для реализации множественного наследования поведений (т.е. наследование от нескольких интерфейсов) никакой необходимости в агрегировании нет.

Цитата:
IA и IB - наследуются, а SomeA и SomeB, реализующие эти IA и IB, агрегируются

Опять ничего не понял, что от чего наследуется? Можно IA и IB и SomeA и SomeB поподробнее расписать?

Цитата:
Что касается явных недостатков... ладно, просто приведи аргументы. Хотя бы один пример недостатка.  

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

Цитата:
Возможности именно что сомнительны. Я только не понял, ты соглашается или споришь?

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

Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 10:25 11-10-2011
Qraizer



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
Разумеется потому, что часто возникает необходимость унаследовать поведение двух сущностей. Полная же реализация множественного наследования как is a является излишней.  
Наследуя интерфейсы, ты не наследуешь их реализации. Интерфейсы суть абстрактные сущности, они не имеют поведения, они его декларируют для своих реализаций. Чьи слова я перефразировал?
Когда в списке базовых классов появляется интерфейс, понятно, что поизводный класс его реализует. Так или иначе. За одним-единственным исключением: если он сам не интерфейс, ибо в этом случае он просто его поглощает и взамен предоставляет другой, более обширный. Но даже в этом случае он его не отменяет, а явно утверждает, что является его расширением. В случае же именно что отмены базового интерфейса наследование должно быть обязательно непубличным.
Когда ты наследуешь реализацию, понятно, что ты являешься в частности и базовым классом, т.е. тебя можно явно использовать везде, где требутся базовый класс. Если это не так, то опять же наследование обязано быть непубличныи, иначе любая функция, получив ссылку на базовый класс, получит в своё распоряжение не его, а нечто им не являющееся. ОО-архитекторы, я нигде не наврал? Подправьте, если что не так.
Теперь ситуация. Я пишу компонент, который в одном флаконе и хранитель логов/истории, и ...эм-м, скажем, socket-ный приёмопередатчик, и несложненький блокнотик++. Что такое? Дикое сочетание, кому это только в голову пришло собрать воедино метры с секундами и залить сверху килограммами? А что, никто QIP не признал? Вы меня удивляете. Ну ладно, это так, лирика, вернёмся к нашим баранам.
У меня есть интерфейсы IHistory, ISocketTransmitter и IRichEdit. Мне ничего не стоит создать свой класс, наследуя все три интерфейса, и реализовав их. Всё пучком? Я тоже проблем не вижу. Да вот незадача: я уже как-то писал их реализации, по две штуки первого и третьего и одну - второго, и у меня есть готовые THistoryFile, THistoryMemory, TTCPTransmitter, RichEditMemos и RichEdit_with_BlackJack_and_Bitchs. Как-то так:
Код:
class THistoryFile                        : public IHistory           { /* ... */ }
class THistoryMemory                      : public IHistory           { /* ... */ }
class TTCPTransmitter                     : public ISocketTransmitter { /* ... */ }
class RichEditMemos                       : public IRichEdit          { /* ... */ }
class RichEdit_with_BlackJack_and_Bitchs  : public IRichEdit          { /* ... */ }
Создавались они в разное время для разных проектов. Что мне делать? Копипастить? Фу-у-ууу, скажут ОО-архитекторы и не только они.
Что делает С++ист?
Код:
class TQIP: public THistoryFile, public TTCPTransmitter, public RichEditMemos
{
/* ... */
};
и горя не знает. Замечу, что базовые интерфейсы IHistory, ISocketTransmitter и IRichEdit никуда не делись. Они по-прежнему в иерархии, так как их реализации THistoryFile, TTCPTransmitter и RichEditMemos явно от них порождены. ОО-архитекторы счастливы? Я тоже не вижу никаких проблем. Более того, я вообще не вижу даже потенциальных источников проблем. Да, класс объединяет в себе три разнородные сущности. И что? Где проблемы-то? А главное - где тут излишество-то? А самое главное - архитектура чётко показывает, кто чем является, кто что использует и как что от чего зависит.
Что делает Дельфист?
Код:
 TQIP = class(IHistory, ISocketTransmitter, IRichEdit)
 strict private
   mHistory    : THistoryFile;
   mTransmitter: TTCPTransmitter;
   mEdit       : RichEditMemos;
 
 protected
   property history    : THistoryFile    read mHistory     implements IHistory;
   property transmitter: TTCPTransmitter read mTransmitter implements ISocketTransmitter;
   property edit       : RichEditMemos   read mEdit        implements IRichEdit;
 
 public
   { ... }
 end;
ну и в общем-то тоже почти не знает горя. А почему почти, я уже говорил в прошлом посте.
Во-первых. Есть класс-дебуггер, например, какая-нибудь реализация шаблона ...ну например Посетитель. (GoF никого не смущает?). Он должен ходить по всем IHistoryFile и собирать статистику для профилирования. Естественно ему и TQIP перепадает. Никаких проблем с его передачей не возникает, TQIP прекрасно кастится к IHistoryFile (ссылки на них, естественно), и Посетитель счастлив.
Но вот мне вдруг понадобилось в Посетителе для TQIP-ов подсобрать чуток больше, для чего мне потребовался интерфейс, скажем, IRichEdit. Я, будучи граммотным ОО-архитектором, не стал "ломать" Посетителя для всего проекта, а решил проблему сугубо локально для себя - реализовал для Посетителя производный класс, в котором перекрыл нужный мне метод.
Внимание, вопрос: как имея запасённый базовым классом IHistoryFile, от его по факту агрегированной реализации перейти к IRichEdit? Я могу ошибаться, но в своё время Дельфисты не удосужились мне ответить, мол, операция AS прекрасно справляется с прыжками между агрегатами одного класса-контейера, когда нам доступны только его базовые интефейсы (код только для демонстрации, так что просьба тапками не кидаться, если кто увидит некомпилябельность, её устранение сделает демонстрацию только хуже):
Код:
PROCEDURE TGuestMore.someMethod(IHistory hist);
 VAR edit: IRichEdit;
BEGIN
 edit := hist AS IRichEdit;
 { ... }
END;
Они просто промолчали, так что я заключил то, что заключил. В то же время C++ист просто напишет
Код:
void TGuestMore::someMethod(IHistory& hist)
{
 IRichEdit& edit = dynamic_cast<IRichEdit&>(hist);
 /* ... */
}
и совершенно пофиг на конкретики реализаций.
Плюсы прозрачнее, они не нагоняют тумана на иерархию, отношения и взаимозависимости. В них всё видно на уровне опубликованных интерфейсов. В Дельфи в общем случае без знания деталей реализации невозможно построить надёжную систему со сложными отношениями между подсистемами. Другими словами, как это ни парадоксально звучит, Плюсы своей прозрачностью позволяют делать черные ящики реально чёрными, а не с альфой под 10%. ОО-архитекторы уже смотрят косо.
Во-вторых. TQIP реализует все три своих интерфейса. Это он так заявляет. На самом же деле он этого не делает. Он взял конкретные реализации этих трёх интерфейсов и их использует. Конечно, если я его автор, у меня проблем нет. Но я не автор, я пользователь этого TQIP, и без того, чтобы зарыться в изучение реализации этого TQIP, я об этом не узнаю, а значит если кому-то взбредёт в голову проапдейтить THistoryFile в нашем проекте, он вот так лёгким движением руки изменит поведение TQIP. Хотя казалось бы какая может быть связь между совершенно разными классами, однако одна из реализаций IHistoryFile оказалась зависимой от другой. ОО-архитекторы бьют тревогу, тут альфа нифига не 10%, все 90 наберётся. Да-да, с Плюсами будет та же картина. Но ведь её явно видно из объявления TQIP. Там явно сказано - TQIP является THistoryFile. Так что тут всё заранее известно и предсказуемо в отличие от.

Цитата:
Запутанность интерфейсной части при частичном перекрывании пространства имен.
Секундочку. У интерфейсов нет этой проблемы?? Нука-нука, вот есть у нас методы IHistoryFile::lifeTime() и ISocketTransmitter::lifeTime(), только первый отвечает за время хранения истории, второй - за время жизни пакета в сети. Интересно, если я вызову TQIP::lifeTime(), что вызовется? ИМХО очень интересный вопрос. Не языковой - архитектурный.

Цитата:
Проблема известная под названием алмаз никсона.
Ромбовидное наследование.
Во-первых, это не проблема. Точнее, это не проблема множественного наследования реализаций. Во-вторых, как раз она ставит крест на множественном наследовании реализаций в Дельфях. Есть ситуации, когда неединственный базовый класс должен быть уникальным на иерархию, есть ситуации, когда он должен входить в неё столько раз, сколько указано. Тот же TQIP к примеру может иметь множество реализаций ISocketTransmitter, по одному на каждый потокол - ICQ, MailRu, GoogleTalk итп. И все эти ISocketTransmitter должны быть неединственными. Ты ж не собираешься предложить компилятору самому решить, сливать или не сливать? Так что это пробема опять же ОО-архитектуры, и решать её требуется в каждом случае явно ОО-архитектором, а не программистом. Так что проблемы алмаза в ООПрограммировании не существует, есть проблема алмаза в ООПроектировании.

Цитата:
Виртуальные конструкторы это фабричный метод в чистом виде, можно и без виртуальных конструкторов, но с ними лучше, намного лучше.
Надо будет потом вернуться к этой теме. Не забыть бы. Но вкратце-таки скажу.
Виртуальных конструкторов не бывает. То, что бывает - инициализаторы. Borland обозвала их конструкторами объектов, её право, но ИМХО это был граммотный маркетинговый, но плохой дизайнерский ход. В Плюсах нет инициализаторов, и это в некоторой степени удручает, не могу не согласиться. То, что есть - это аналог Дельфийских конструкторов классов, но те и в Дельфи не могут быть виртуальными.
Фабрика, реализованная прямо в языке - это удобно, когда нужно. Как показывает практика, нужно оно менее чем в ~10% случаев. Мягко говоря, постоянное её наличие во всех классах - это слишком высокая плата за потерю эффективности кода, сложность кастомизации фабрики, невозможность вменяемой реализации RAII, невменяемость безопасного к исключеняим кода, пестрящего TRY/FINALLY, невозможность разделить ответственность за инварианты между классами в иерархии да и отсутствие инвариантов как таковых.
Сорри, тут только факты без аргументации. Просто не думаю, что будет продуктивно говорить подробно сразу обо всём. Написал, просто чтоб не потерялось.

----------
Одни с годами умнеют, другие становятся старше.

Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 03:31 12-10-2011
shotfire



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
самое главное преимущество ООП сокращение объема строк исходного кода

Всего записей: 231 | Зарегистр. 17-07-2005 | Отправлено: 04:46 12-10-2011
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Qraizer

Цитата:
Написал, просто чтоб не потерялось.

:)
я б за интернет-публикацию зачёл...
 
shotfire
и блок-схемы иногда можно не рисовать...

Всего записей: 24115 | Зарегистр. 06-12-2002 | Отправлено: 07:26 12-10-2011 | Исправлено: akaGM, 07:39 12-10-2011
wasilissk

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Qraizer

Цитата:
Интерфейсы суть абстрактные сущности, они не имеют поведения, они его декларируют для своих реализаций.

Поведение сущности однозначно описывается её интерфейсом. Объект это сущность с поведением и состоянием. Наследование реализации - это наследование поведения и состояния, наследование интерфейса - это наследование поведения. Это уже совсем букварь, безотносительно языка программирования это есть у Буча, есть у гофов.

Цитата:
 В случае же именно что отмены базового интерфейса наследование должно быть обязательно непубличным.

В delphi нет публичных наследований. Вообще сама фраза относительно delphi кощунственна. Интерфейс это то, что публикуется, необходимость отменять интерфейс говорит об ошибках проектирования. То, что не должно публиковаться просто вообще не должно  попадать в интерфейс.
В примере про TQip.
 
Цитата:
И что? Где проблемы-то? А главное - где тут излишество-то?

Объединять совершенно различные сущности в одну суперсущность - есть главная проблема, это противоречит ООП в частности и здравому смыслу в целом. Если кратко пример с TQip-ом - это пример о том, как написать говнокод на C++ в одну строчку, и о том, что на делфи говнокод получится значительно длиннее. Причем делфи будет всячески мещать в написании говнокода. Я же не спорил с тем, что множественное наследование поведений это не совсем то, или даже совсем не то, что множественное наследжование, я даже сам написал что это не одно я то же.  

Цитата:
Внимание, вопрос: как имея запасённый базовым классом IHistoryFile, от его по факту агрегированной реализации перейти к IRichEdit?

Выше было написано, что есть ссылка на TQip, если так, то есть ссылка на все его интерфейсы, проблемы нет. Если нет ссылки, то в виртуальный конструктор "производного классе Посетителя" можно передать ссылку на экземпляр IRichEdit? C++ так умеет?  

Цитата:
Плюсы прозрачнее, они не нагоняют тумана на иерархию, отношения и взаимозависимости.

За жесткое приведение IHistoryFile к IRichEdit стоит убивать на месте. В данном случае то, что С++ позволяет это делать является безоговорочным минусом C++.

Цитата:
В них всё видно на уровне опубликованных интерфейсов. В Дельфи в общем случае без знания деталей реализации невозможно построить надёжную систему со сложными отношениями между подсистемами. Другими словами, как это ни парадоксально звучит, Плюсы своей прозрачностью позволяют делать черные ящики реально чёрными, а не с альфой под 10%. ОО-архитекторы уже смотрят косо.

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

Цитата:
Но я не автор, я пользователь этого TQIP, и без того, чтобы зарыться в изучение реализации этого TQIP, я об этом не узнаю, а значит если кому-то взбредёт в голову проапдейтить THistoryFile в нашем проекте, он вот так лёгким движением руки изменит поведение TQIP.

В С++ все точно так же.

Цитата:
Хотя казалось бы какая может быть связь между совершенно разными классами, однако одна из реализаций IHistoryFile оказалась зависимой от другой.

Ни в коем случае, одна реализация никоим образом не влияет на другую.

Цитата:
Да-да, с Плюсами будет та же картина. Но ведь её явно видно из объявления TQIP. Там явно сказано - TQIP является THistoryFile.

Опа, приехали. Из всего вышеозвученного вообще не понятно зачем нужны интерфейсы IHistory, ISocketTransmitter и IRichEdit? Если работа по сути везде идет с TQip и конкретными реализациями THistoryFile, THistoryMemory, TTCPTransmitter, RichEditMemos и RichEdit_with_BlackJack_and_Bitchs? Создай TQip непосредственно с THistoryFile, TTCPTransmitter,RichEditMemos и никаких проблем с черными ящиками и альфаканалами не будет.  

Код:
TQIP = class(TObject)  
private  
   mHistory    : THistoryFile;  
   mTransmitter: TTCPTransmitter;  
   mEdit       : RichEditMemos;  
public  
   property history    : THistoryFile    read FHistory;  
   property transmitter: TTCPTransmitter read FTransmitter;  
   property edit       : RichEditMemos   read FEdit;  
end;

Если под переменную IHistory динамически подставляют различные реализации - сравнение вообще некорректное ибо функционала аналога класса С++ просто недостаточно. Есть подозрение, что ты просто не умеешь готовить интерфейсы, они в данном примере ну просто не нужны.
 
Я же хотел увидеть пример, в каких таких ситуациях множественного наследования поведения может быть недостаточно. В ситуациях правильного проектирования жизненной задачи, без приведений ISantehnik к IOsinoviiKol.  
Я утверждаю, что таких ситуаций просто нет.
А если начать высасывать аргументы из пальца можно написать, а С++ может автоматически освободить объект IHistory, когда он выйдет за пределы видимости, писать вызовы деструкторов это ведь так утомительно.
Теперь, о том что делать.

Цитата:
Создавались они в разное время для разных проектов. Что мне делать? Копипастить? Фу-у-ууу, скажут ОО-архитекторы и не только они.

Создавать экземпляры по месту их использования. Более подробно можно говорить только после обрисовки задачи. Пока что целесообразность фасада TQip совершенно не ясна.
 

Цитата:
ИМХО очень интересный вопрос.

В реализации указывается перед именем метода, имя интерфейса.

Цитата:
Во-вторых, как раз она ставит крест на множественном наследовании реализаций в Дельфях.

Крест на множественном наследовании реализаций в Дельфях ставит здравый смысл.

Цитата:
Так что это пробема опять же ОО-архитектуры, и решать её требуется в каждом случае явно ОО-архитектором, а не программистом.

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

Цитата:
Виртуальных конструкторов не бывает. То, что бывает - инициализаторы.


Цитата:
То, что есть - это аналог Дельфийских конструкторов классов

Э-э-э, а подробнее?

Код:
constructor Create(a: integer); virtual;
 
Почему это не конструктор? И что есть конструктор класса?

Цитата:
Фабрика, реализованная прямо в языке - это удобно, когда нужно.

Что за фабрика? Абстрактная фабрика? Я не об этом, фабричный меnод это другой паттерн.

Цитата:
Как показывает практика, нужно оно менее чем в ~10% случаев.

10% случаев от чего?

Цитата:
Мягко говоря, постоянное её наличие во всех классах - это слишком высокая плата за

Что за фабрика опять же?

Цитата:
потерю эффективности кода

В чем закючается?

Цитата:
сложность кастомизации фабрики

?

Цитата:
невозможность вменяемой реализации RAII,  

Чек. В конструкторе этого лучше не делать. Cоглашусь это минус.

Цитата:
невменяемость безопасного к исключеняим кода, пестрящего TRY/FINALLY

try/except наверно имелось ввиду? В конструкторе этого делать просто неправильно, эта проверка должно быть в коде клиента. Тогда все ок.

Цитата:
невозможность разделить ответственность за инварианты между классами в иерархии да и отсутствие инвариантов как таковых.

Инварианты это глобальные переменные? Или что это в данном случае?

Цитата:
Сорри, тут только факты без аргументации.

Сорри, cлишком страшные обвинения, без аргументов не принимается.

Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 09:22 12-10-2011
Qraizer



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
wasilissk, ты ничего не понял. Сожалею.
 
Добавлено:

Цитата:
Интерфейс это то, что публикуется, необходимость отменять интерфейс говорит об ошибках проектирования. То, что не должно публиковаться просто вообще не должно  попадать в интерфейс.  
Отмена интерфейса не означает конец его существования. Ты перечитался COMом, без которого Дельфи и не Дельфи вовсе. Отмена интерфейса означает, что им просто не дают пользоваться за определёнными пределами, например, некой классовой иерархии, потому что этот интерфейс не открывается вовне, но он используется внутри, во-первых, о чём явно сообщается наследованием от него, во-вторых, предоставляя возможность подкладывать различные его реализации этой иерархии.

Цитата:
Объединять совершенно различные сущности в одну суперсущность - есть главная проблема, это противоречит ООП в частности и здравому смыслу в целом.
Сам понял, что сказал? В таком случае здравому смыслу противоречит, например, FireFox, который просто пестрит совершенно различными сущностями в лице плагинов, и где они все под одной суперсущностью - браузером.

Цитата:
Выше было написано, что есть ссылка на TQip, если так, то есть ссылка на все его интерфейсы, проблемы нет. Если нет ссылки, то в виртуальный конструктор "производного классе Посетителя" можно передать ссылку на экземпляр IRichEdit? C++ так умеет?  
Опять же, ты ничего не понял. Посетителя интересует только IHistory. TQIP его предоставляет, поэтому он тоже им будет посещаться. Тот факт, что для более ёмкой статистики в неком частном случае потребовалась TQIPовая информация, которая может быть получена от него через IRichEdit, означает не более чем то, что в этом частном случае потребовался частный Посетитель, который легко может быть получен наследованием и перекрытием одного метода. И только в этом методе потребовался другой TQIPовый интерфейс, а именно IRichEdit. Простая же задача - перейти от IHistory к IRichEdit.

Цитата:
За жесткое приведение IHistoryFile к IRichEdit стоит убивать на месте. В данном случае то, что С++ позволяет это делать является безоговорочным минусом C++.  
Дельфийный AS таков же. Так же бросит эксепнш в run-time, как и C++.

Цитата:
Я утверждаю, что таких ситуаций просто нет.
Нда? Привести пример "попроще"? У Александреску посмотри. Его смарт-поинтер - это нечто.
Вообще, что касается множественного наследования реализаций, так паттерн Стратегия - чи как там её - с помощью которой параметризуется поведение, нынче считается одной из самых красивых, мощных и гибких.

Цитата:
Крест на множественном наследовании реализаций в Дельфях ставит здравый смысл.  
Ну если за пределами Дельфи ООП не существует, то вероятно да. Только вот незадача: в мире ОП иметь объекту много предков - это норма, а простое наследование скорее случаейное исключение. Это только в мире ООП с этим сложности. Слава богу не у всех ООП-языков.
Касательно остального, что не комментировал, внимательно, а не по диагонали, перечитай прошлый пост. Можно не один раз перечитать, если покажется сложным. Потому как там все ответы есть, а чего нет, так то азбука. Я может и холиварщик, но не преподаватель нахаляву и тем более не тавтолог.

Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 05:40 13-10-2011
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » В чем преимущество ООП ?


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru