Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» В чем преимущество ООП ?

Автор: druff
Дата сообщения: 07.10.2011 09:01
wasilissk
Какими именно концепциями? RAD?
Автор: wasilissk
Дата сообщения: 07.10.2011 12:37
druff
Визуальное программирование, подход к реализации ООП (напр. множественное наследование, наследование интерфейсов, виртуальные конструкторы), типизация (о чем говорил Qraizer здесь http://forum.ru-board.com/topic.cgi?forum=33&topic=4312&start=100#3).
Автор: delover
Дата сообщения: 08.10.2011 16:20
wasilissk

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

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

Добавлено:

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

Это концепция Delphi?
Автор: wasilissk
Дата сообщения: 08.10.2011 20:09
delover
Э-э-э, никак не мог догнать, чего вы от меня хотите.
Прочитал еще раз сообщение.

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

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

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

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

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

А что тогда?
Автор: Qraizer
Дата сообщения: 08.10.2011 22:43
Концепции ссылочных типов, как я понимаю.
Автор: delover
Дата сообщения: 09.10.2011 02:17
wasilissk
Тогда, значит, Вы не поняли моё сообщение, а я Ваше. )))

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

Ну это пустяки конечно. Язык влияет только на мышление.

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


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

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

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

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

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

И-и-и?..

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

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

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

Куда уж веселее. Презабавный факт, наличие встроенных визуальных редакторов, заточенность проектирования от визуального представления, свое видение MVC это все ничего не значащий факт. А вот тонкости в реализации RTTI это умотаться какая важная вещь - концепция никак.
Кстати, как там насчет чего-то общего у С и C# помимо синтаксиса?
Автор: delover
Дата сообщения: 09.10.2011 19:39
wasilissk
[no][/no]

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

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


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

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


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

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


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

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


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

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


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

Ну перечитайте вдумчиво что написано было.
[no]http:||ru.wikipedia.org/wiki/Model-View-Controller[/no]
Ничего не понял.
Автор: wasilissk
Дата сообщения: 09.10.2011 21:19

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

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

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

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

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

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

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

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

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

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

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

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

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

Где читать? Процитируйте, будьте милостивы.
Автор: Qraizer
Дата сообщения: 10.10.2011 01:25

Цитата:
...надо полагать сишарп пострадал, что в нём нет ссылок?
delover, нет. Он пострадал тем, что нет единой семантики для всех типов. В C++ все типы нессылочные, и есть отдельный тип - ссылка на что-либо. Упрощённо говоря, любой тип можно сделать ссылочным по требованию дизайна.
Дело не в том, что ссылочные типы - зло. В Питоне всё наоброт - все типы ссылочные, и это тоже нормально. Ненормально - когда половина так, половина эдак. Когда я пишу
Код: template <typename T>
T add(T x, T y)
{
x += y;
return x;
}
Автор: wasilissk
Дата сообщения: 10.10.2011 06:54
Qraizer

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

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

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

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

Код:
int i = 3; object o = (object)i; byte b = (byte)i;
// box conv - похоже на конвертацию
Автор: delover
Дата сообщения: 10.10.2011 17:27
Эмм.
Тогда стоит продолжить. Появляется, значит, у разработчика Дельфи время поработать в Сишарп. За годы работы глаза его стали видеть хуже и некоторое время в Сишарпе он видит только Дельфи. Хотя приложение не выходит, его глаза начинают привыкать и потихоньку возникает момент узнавания. Да, вот это, вот так вот должно быть в Си. И в этот момент приложение начинает получаться. Возможно от радости, а возможно из-за вполне здравых предпосылок он говорит - Сишарп больше похож на Си (для него он стал более похож на Си и всё стало получаться). Знал ли он тогда, что если бы он хотел в глазах девочек выглядеть знатоком Си, то понимал бы - надо говорить Сишарп не похож на Си? Наверно не знал. Да в точно таких чуствах - радости, что кое чего получилось был добавлен пост про схожести.
Автор: Qraizer
Дата сообщения: 10.10.2011 23:36

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

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

P.S. Я никогда не холиварю без фактов, но и ожидаю аналогичного от оппонентов.
Автор: wasilissk
Дата сообщения: 11.10.2011 09:25
Qraizer

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

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

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

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

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

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

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

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

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

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

Цитата:
Разумеется потому, что часто возникает необходимость унаследовать поведение двух сущностей. Полная же реализация множественного наследования как 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 { /* ... */ }
Автор: shotfire
Дата сообщения: 12.10.2011 03:46
самое главное преимущество ООП сокращение объема строк исходного кода
Автор: akaGM
Дата сообщения: 12.10.2011 06:26
Qraizer

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

:)
я б за интернет-публикацию зачёл...

shotfire
и блок-схемы иногда можно не рисовать...
Автор: wasilissk
Дата сообщения: 12.10.2011 08:22
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;
Автор: Qraizer
Дата сообщения: 13.10.2011 04:40
wasilissk, ты ничего не понял. Сожалею.

Добавлено:

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

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

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

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

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

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

Добавил


Цитата:
Отмена интерфейса не означает конец его существования.

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

Цитата:
Ты перечитался COMом, без которого Дельфи и не Дельфи вовсе.

Интерфейс уже давно много больше чем com.

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

Когда в некой иерархии приходится прятать методы которые в предках имели большую видимость, такая иерархия порочна, ее надо переделывать. Читаем принцип замещения Лисков до просвещения. И принцип single responsibility заодно.

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

Т.е. система плагинов FireFox-а такова, что некая сущность(супер-пупер-классс) наследуется от всех классов плагинов и от супер-класса браузера и предоставляет свой объединенный интерфейс супер-пуперт-класса ТБраузерСПлагинами для работы со всем сразу? Именно этим и занимается TQip в прошлом примере. Это какое-то процедурное программирование получается. Конечно это противоречит здравому смыслу, хотя я очень сомневаюсь в FireFox-е работает именно так как ты описал. Я еще раз повторяю, есть паттерн фасад, но в него не тащат все подряд, и не вытаскивают все в интерфейсную часть без разбора.

Цитата:
Тот факт, что для более ёмкой статистики в неком частном случае потребовалась TQIPовая информация, которая может быть получена от него через IRichEdit, означает не более чем то, что в этом частном случае потребовался частный Посетитель, который легко может быть получен наследованием и перекрытием одного метода.

Полностью переопределять поведение класса в его потомке – дурнейшая практика, ничего нормального в ней нет. Читаем принцип замещения Лисков до просвещения.

Цитата:
И только в этом методе потребовался другой TQIPовый интерфейс, а именно IRichEdit.

Я ответил на этот запрос в предыдущем посте. Delphi позволяет написать и этот говнокод, передаем потомку этого посетителя интерфейсную ссылку IRichEdit от класс TQip в перегруженном конструкторе.

Цитата:
Нда? Привести пример "попроще"? У Александреску посмотри. Его смарт-поинтер - это нечто.

Это вообще к чему? Для смарт-поинтеров нужно множественное наследование? Или это к подсчету ссылок? Если второе, так не канает - в Delphi это из коробки, мы же тут, высасывая из пальца, строки кода считаем.

Цитата:
Вообще, что касается множественного наследования реализаций, так паттерн Стратегия - чи как там её

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

Цитата:
Только вот незадача: в мире ОП

Что еще за мир ОП? Хотелось бы почитать про мир, где потомок наследуется от четырех родителей, включая полностью или частично их тела в себя. Думаю будет увлекательное чтиво.

Цитата:
Касательно остального, что не комментировал, внимательно, а не по диагонали, перечитай прошлый пост. Можно не один раз перечитать, если покажется сложным. Потому как там все ответы есть, а чего нет, так то азбука. Я может и холиварщик, но не преподаватель нахаляву и тем более не тавтолог.

Там очень много текста, я его внимательно прочитал, честно, ничего сложного не нашел, ответов тоже нет; есть ошибки, неуместные примеры (зачем в частности там вообще интерфейсы ты так и не ответил), неаргументированные высказывания. В ученики не набиваюсь, уволь.
Автор: Eternal_Shield
Дата сообщения: 13.10.2011 08:12
wasilissk
Берите пример с меня и никому ничего не доказывайте Если слон верит что он синий, значит он действительно синий

А если серьёзно, то нельзя человеку показать тот путь, который он не хочет видеть. Это было видно по второму посту. У меня сложилось такое впечатление, что человечек волею судеб пересел (на работе) на делфи с с++, а логика то уже разбита об сверх-ООП в С++ и пути назад нет. Вот и протестует.

Кстати, знаю как минимум 2х людей, которые были ярыми противниками Delphi и садиться за него не хотели. Зато перешли с С++ на шарп и поняли чего им религия (запрещала/не давала) все эти годы

З.Ы: А Хейлсберг-то (и все последователи С#), наверно, не в курсе гигантских проблем с ооп в Delphi/C#.
Автор: wasilissk
Дата сообщения: 13.10.2011 08:48
Eternal_Shield

Цитата:
А если серьёзно, то нельзя человеку показать тот путь, который он не хочет видеть.

Ну я на это и не претендую. Убедить кого-то задачи нет, так просто отвлеченная беседа на тему ооп.
Автор: rrromano
Дата сообщения: 13.10.2011 09:39
wasilissk
Вот, я как раз собирался что-то написать по поводу, а вы уже всё рассказали ))).
Автор: wasilissk
Дата сообщения: 13.10.2011 10:51
rrromano

Цитата:
а вы уже всё рассказали

Да неужели таки все?
Напишите, мне интересно.
Автор: rrromano
Дата сообщения: 13.10.2011 14:00
wasilissk
Ну, по крайней мере, это больше, чем я хотел. Я всего-лишь по множественному наследованию хотел пройтись )))
Автор: Qraizer
Дата сообщения: 15.10.2011 08:27

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

Цитата:
Еще раз повторяю, в Delphi невозможно отменить интерфейс.

Цитата:
Если тебе этого не нужно, не стоит их выносить в этот интерфейс.

Цитата:
Интерфейс уже давно много больше чем com.

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

Цитата:
...
Секундочку и по порядку.
Во-первых, Дельфи тут причём? Я предъявил ТЗ, а к реализациям на языках я перешёл после этого. Ты даже этого не понял? Впрочем, ты и тут неправ, отменить интерфейс в Дельфи можно, а иногда и нужно, и опять же Дельфи тут не причём, причём - архитектура подсистем.
Во-вторых, и это связано с во-первых. Интерфейсы требуются для регламентирования требований к реализациям. Если некая сущность является внутренней деталью некой подсистемы, почему её нельзя регламентировать? И если можно, то почему при этом обязательно раскрывать наружу? Похоже тебе самому Лисков перештудировать не помешало бы.
В-третьих, вот чему-чему, но учить меня проектировать не следует. Дельфи вот - можно, я его не знаю достаточно хорошо, чтобы отвечать за все свои слова о нём. Но вот проектированию больших, гибких и масштабируемых систем... ладно, я реалист... есть куда ещё расти, но учить меня не тебе явно. Ты уже дваджы накололся на принципах Лисков.
В-четвёртых. Не понравился пример с браузером? А что с ним не так? Какая разница, как оно там внутри реализовано и как спроектировано? Но ведь он явно попадает под твоё определение говнопродукта, ибо вмещает в себя кучу разнородных сущностей.
В-пятых. Ладно. Предположим ты поколебал мою уверенность касательно TQIP. Тогда укажи пальцем, где просчёт. Вернёмся к ТЗ. Итак.
Требуется компонент, реализующий три интерфейса. Пока всё в порядке? Ничего необычного?
Каждый интерфейс по отдельности уже реализован и не однажды. Диссонанс не возник? Будет весьма странно, если вдруг.
Некоторые из этих реализаций уже подходят нашему компоненту. Так не бывает? От ёлки, а мужуки-то не знают.
Когда мне подходит некая реализация, я имею право, основываясь на ней как на базе, задействовать её у себя, и при этом согласно принципу Лисков наследование должно быть публичным, ибо новый класс в частности является и базовым и может выступать всемто него везде, где необходим базовый. Неужели прокол тут?
Я беру три подходящих мне реализации, по одной на каждый интерфейс, и получаю свой компонент. Э-э-э...Жду комментов. Очень хочется в спойлере предсказать, каких именно, но сдержусь.

Цитата:
Полностью переопределять поведение класса в его потомке – дурнейшая практика, ничего нормального в ней нет. Читаем принцип замещения Лисков до просвещения.

Цитата:
передаем потомку этого посетителя интерфейсную ссылку IRichEdit от класс TQip в перегруженном конструкторе.
Ладно, и это разжую. Это не полное переопределение, а кастомизация. Предположим Посетитель используется для оценки эффективности кеширования строк объектами IHistory. TQIP (сейчас совершенно неважно, каким именно способом он составлен из кирпичиков) безусловно должен будет быть помещён в коллекцию к Посетителю для опроса. Так уж получилось, что реализация IRichEdit разделяет с IHistory несколько последних строк истории. Открой QIP, ну или вообще любой пейджер, так и есть. Поэтому для более точной статистики требуется это число получить также и от реализации IRichEdit и вычесть из значения, полученного у IHistory.
Посетитель используется во всём проекте, а не ради каких-то жалких экземпляров TQIP, всего IHistory в проекте десятки. Коллекция у него хранит ссылки на IHistory. С какого перепугу он должен нормально отнестить к передаче ему IRichEdit? Что делать? Переделывать? Я уже показал наиболее правильный метод, использующий только локальное вмешательство на уровне одной-единственной подсистемы. Разумеется от базового класса локальному посетителю придёт IHistory, но он-то знает, что некоторые из них могут оказаться экземплярами TQIP, и если это так, то требуется получить от него IRichEdit, вызвать там единственный метод и вычесть. Делов-то:
Код: std::size_t getLinesCount(const IHistory* hist)
{
const IRichEdit *edit = dynamic_cast<const IRichEdit*>(hist);
std::size_t linesAmount = hist->getCachedLines();

if (edit != NULL) linesAmount -= edit->getCurrentLines();

return linesAmount;
}
Автор: Eternal_Shield
Дата сообщения: 15.10.2011 15:18

Цитата:


Код: FUNCTION getLinesCount(hist:IHistory):Cardinal;
VAR edit:IRichEdit;
BEGIN
Result := hist.getCachedLines;

TRY
edit := hist AS IRichEdit;
Result := Result - edit.getCurrentLines
EXCEPT
END
END;

У меня только один вопрос: будет ли это работать в Дельфи?
Автор: wasilissk
Дата сообщения: 16.10.2011 09:52

Цитата:
Ты бы предпочёл увидеть скопипасченный пост? Странно. rrromano, ты прав, в моём посте всё есть, но.

Я написал это когда увидел в качестве ответа

Цитата:
ты ничего не понял. Сожалею.

И ничего более. После того как твой пост был дополнен, я дополнил и свой.


Цитата:
Во-первых, Дельфи тут причём?

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

Цитата:
Но касательно Дельфи - её там не может быть в связи с самой моделью ООП.


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


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



Цитата:
Я предъявил ТЗ, а к реализациям на языках я перешёл после этого. Ты даже этого не понял?

Ну вот только не надо доказывать, что белое это черное. Разговор об интерфейсах начался еще до твоего ТЗ.

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

Как?

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


Цитата:
И если можно, то почему при этом обязательно раскрывать наружу?

Ну регламентируй в интерфейсе поведение сущности, хочешь - скрой в этой системе, хочешь – опубликуй; что эти твои слова доказывают или что опровергают? И как они вообще связаны с

Цитата:
Похоже тебе самому Лисков перештудировать не помешало бы.

Иерархия, в которой скрываются методы, опубликованные в предке, просто по определению не удовлетворяет принципу замещения Лисков, потому что потомок не может выступать на месте предка. Ты с этим спорить собираешься?

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

Мы знакомы? Не понимаю, к чему эта пустозвонная бравада. Предлагаю на этом завершить переход на личности и ограничиться обсуждением ООП.

Цитата:
Ты уже дваджы накололся на принципах Лисков.

Где? Цитату, пожалуйста.

Цитата:
Не понравился пример с браузером? А что с ним не так?

Т.е. мне в третий раз написать то же самое?

Цитата:
Какая разница, как оно там внутри реализовано и как спроектировано?

Т.е. как оно внутри все равно, лишь бы работало. Ну-ну. Мы все еще про ООП или уже про что-то иное?

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

Ложь и искажение, я не об этом писал.

Цитата:
Жду комментов. Очень хочется в спойлере предсказать, каких именно, но сдержусь.

Снова да ладом, ок, дубль три.
В предложенной тобой делфийской реализации интерфейсы не нужны. Агрегируем три этих реализованных класса и публикуем ссылки на них, все.
В данном новом абстрактном изложении это фасад, целесообразность которого в конкретном примере TQip ты так и не аргументировал. Отдельно напоминаю, что ты говорил о каких-то архитектурных преимуществах варианта C++, предложив в качестве иллюстрации этого преимущества прямое преобразование ничем не связанных семантически интерфейсов.

Цитата:
Опять же, ты ничего не понял. Посетителя интересует только IHistory.


Цитата:
Это не полное переопределение, а кастомизация.

Кастомизация это преобразование одного типа к другому. Если изначально посетитель проектировался исключительно для работы с IHistory, а его потомок с никоим образом не связанным с ним IRichEdit-ом стал работать - это называется полным переопределением поведение класса в его потомке.

Цитата:
будет ли это работать в Дельфи?

Будет

Код:
VAR qip: TQip;
edit:IRichEdit;
begin
qip := TQip(Hist);
if qip.QueryInterface(IRichEdit, edit) then
работаем с edit
else
работаем c Hist
Автор: delover
Дата сообщения: 16.10.2011 16:11
Qraizer

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

В Дельфи это реализуется весьма просто, до банальности, хотя если интерфейс уже прописан будет диссонанс между объявлением компилятору и саппортом Query. Диссонанс легко можно сопроводить ссылками на источник+комментами девелоперу, что и нужно всегда делать. Наверно между проектированием и научной теорией тоже бывает диссонанс.


Цитата:
5. Я беру три подходящих мне реализации, по одной на каждый интерфейс


Цитата:
Ну вот только не надо доказывать, что белое это черное

Уже неплохо для начала ) только я не хореограф. Оба пика оторваны от базовых величин к коим предлагаю вернуться, а именно синтаксис и прагматика. (Отступление, скажу честно, есть 3 реализации готовые я делаю копи паст и перевариваю в одну, - дольше на 1 час, надёжнее на полгода ИМХО, потому что лучше запомню и реже буду изменять код). И так:
СИНТАКСИС
1. Предположим имеется type TMyBoolean = Boolean?. (true,false,null).
2. Классическая конструкция if Conditional then, для этого типа заменяется методом IfThen3(TMyBoolean,1,2,3).
3. Допустим существует доп.указание как это используется на сотне другой проектов.
Я уважаю мнение человека который скажет что это не синтаксис, что это вроде даже не язык Си. Но мне где то в глубине будет так жаль учёных которые придумывали всякие понятия о формализованном языке и мета языке. Для них то IfThen3 вполне себе синтаксис. Да он подразумевает внутри байты или inline/template, и что с того если для всей проектируемой системы требуется формализовать задачу в соответствии с сущностями задачи. Это полноправный синтасис, но не вселенского масштаба конечно.

ПРАГМАТИКА
Дисциплина от греческого слова - польза (*или дело, неважно уже столько раз всё менялось).
1. Допустим было доказано что кастомизация это преобразование одного типа к другому.
2. Предположим первый тип является в иерархии наследования предком второго типа.
3. Предположим что за доказательство номер 1 нужно определить гонорар.
В ситуации когда выясняется, что в предке уже есть всё для преобразования помогает прагматика - избыточные доказательства. Без выделения общего (в преобразуемом субъекте), понятие кастомизации займёт место на полке с другими ненужными понятиями ИМХО.

Книг перечислить не могу ниодной. )
*Исправлено*

*Добавлено*
Забываю, если сохряняется условие выполнимости, сложно согласиться с утверждением о невыполнимости множественного наследования.

Страницы: 1234567

Предыдущая тема: Сервис работы с файлами


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.