"Узнаю тип, и узнаю калибр!" (c) Л. Буссенар
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 13.05.06 05:22
Оценка: 25 (5) +4 :))
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


МН побуждает к специфическому дизайну. Пользоваться таким подходом или нет — вопрос вкуса.

VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Пример с интрузивными списками уже приводили. Ещё посмотри на потоки STL...

Хотя, конкретные примеры здесь всё равно ничего не дадут, потому что:

а) Без множественного наследования обойтись можно всегда;
б) Без наследования тоже обойтись можно всегда;
в) Без ООП также обойтись можно всегда;
г) Янус написан без множественного наследования.

И любой приводимый пример можно по такой схеме разнести в квантовую пыль, а значит, "доказательства" на конкретных примерах можно сходу объявлять несостоятельными. И в некотором роде, это правильно. Примерами вообще нельзя доказать необходимость существования чего-либо конкретного. Примерами можно что-то опровергнуть, усилить свою позицию или проиллюстрировать высказывание. Однозначно доказать необходимость — практически невозможно.

Если хочешь, то это как раз случай NP-полной задачи: придётся перебрать все возможные варианты решений конкретной задачи и если на всём множестве решений фича YYYY даёт наиболее эффективные результаты, то лишь тогда можно будет считать, что её необходимость доказана. Но задачу надо брать достаточно увесистую — например, CRM какой-нибудь или чё поширше, одними только отдельно взятыми группами классов не обойдёшься.

Так что, получается, что ты побуждаешь собеседников к заведомо проигрышной позиции — что бы они не сказали в защиту МН, всё может быть опровергнуто слёту.

PS.: Собственно, сказанное выше уже прекрасно подтверждено ходом дискуссии.

PPS.: Есть только одна группа аргументов, которая перевешивает десятки мегабайт трафика таких дискуссий. Начинаются аргументы этой группы со слов: "Я хочу".
... << RSDN@Home 1.2.0 alpha rev. 643>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[2]: Множественное наследование, mix-in-ы, traits
От: IT Россия linq2db.com
Дата: 10.05.06 20:47
Оценка: +3 :))) :)))
Здравствуйте, Kluev, Вы писали:

K>
K>    : public QS_Object // базовый стафф
K>

Наиболее точный перевод слова 'стафф' с английского, передающий практически 100% смысл этого слова — это русское слово 'хрень'. Так бы сразу и писали — базовая хрень

Ничего личного, просто повеселило употребление stuff в таком виде
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 11.05.06 12:32
Оценка: 1 (1) +3 -1
Здравствуйте, dshe, Вы писали:

D>Цели, ради которых и было придумано множественное наследование, вроде бы ясны. Однако, на мой взгляд множественное наследование реализации (по крайней мере в том виде, в каком оно реализовано в C++) чревато граблями больше, чем дает преимуществ.


Граблями черевато абсолютно все даже int,
надо юзать фичи там где они уместны и не юзать там где они неуместны.

Если м-н юзается чтобы соединить две ветвистые иерархии классов, то грабли обеспечены.
М-н совершенно безопасно если все подмешиваемые к одной иерархии классы sealed (т.е. спроектированы так чтобы не иметь наследников).
Re[9]: Множественное наследование, mix-in-ы, traits
От: Cyberax Марс  
Дата: 12.05.06 09:29
Оценка: 5 (2) :)
dshe wrote:
> Я здесь более акцентировал внимание на то, что у mixin'а лучше было бы
> иметь четко определенный контракт, который, в свою очередь, мог бы
> помочь обнаружить проблемы на более ранних стадиях компиляции и,
> возможно, с более понятной диагностикой.
Welcome to C++09 Там вводят понятие модели и концепта, то есть на
миксин (делающийся с помощью CRTP) можно поставить ограничение (типа
"подмешивать только к CopyConstructible классам").
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[5]: Множественное наследование, mix-in-ы, traits
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 13.05.06 03:02
Оценка: 1 (1) +1 -1
Здравствуйте, VladD2, Вы писали:

K>>А это пример значит неконкретный?

VD>Это вообще не пример. Пример подразумевает объяснение целей и решений. Здесь же не ясно что и зачем.



K>>Пример вполне тривиальный и жизненный. Грубо говоря обьект разделяется м-ду двумя документами. Один — модель, владелец всех обьектов, через которую идет вся работа с данными, другой документ 3-д сцены,

VD>О как. Мы противопоставляем модль и документ. А что же тогда такое документ как не модель?

В контексте MVC — одно и то же. В конкретных случаях этот термин может иметь любую семантику. Всё зависит от условий. Могут быть и документы контроллера.

K>> который юзается для отрисовки и UI манипуляций. т.е. не классичесский doc — view, а doc — proxy_doc — view. Где doc — модель, proxy_doc — сцена3д, view — окно_сцены.

VD>Нда. Эту уже на концептуальном уровне выглядит страшно. Раньше все было просо "модель-представление-контроллер". Как разновидность интеграция контроллера в представление. Прокси использовался для создания переходника интерфейса. А тут прям новые концепции. Вот только один вопрос. А оно надо?

А что тут не так? doc содержит исходные сущности, proxy_doc — базовое 3D-отображение, view — проекцию с заданными параметрами. Терминологически не совсем корректно, но не более того.

K>> Преимущества такого подхода очевидны.

VD>Кому, простите?

Мне. Достаточно?

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

VD>Ясно. А может вы просто про контроллер забыли?

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

K>> Если бы вид одевался бы непосредственно на модель,

VD>Что?

Если бы не было промежуточной развязки между основной моделью и сценой в виде 3d-модели.

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

VD>Ну, вот мы и пришли к странному дизайну.

Это совершенно корректный дизайн: создание промежуточного представления, когда сложность сочетаний растёт пропорционально произведению типов данных взаимодействующих слоёв. Ближайшая аналогия — p-код front-end компиляторов. Или же — представление триадами/тетрадами.

Здесь вполне логично использование связи с двумя "модельными" документами.

doc_3d --> some_object <-- doc_model


doc_3d использует часть интерфейса some_object для своей работы, doc_model, как я понимаю, полностью управляет some_object-ом. Что-то не пойму, в чём здесь проблема? И таки да, вполне возможно использовать унаследовать some_object от двух типов узлов списков — список элементов doc_model и список элементов doc_3d. Можно поспорить об эффективности такого решения, но однозначно заявлять о его "странности" неверно.
... << RSDN@Home 1.2.0 alpha rev. 643>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re: Множественное наследование, mix-in-ы, traits
От: Шахтер Интернет  
Дата: 10.05.06 20:34
Оценка: 34 (2)
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Допустим, у нас есть интерфейс

  interface IByteWriter
   {
    void put(byte b);
   }


Данный интерфейс я могу использовать как "базовый класс" при построении некоторой реализации класса -- потока байтов.

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

  interface IByteWriter
   {
    void put(byte b);
    
    struct UintToBytes
     {
      byte b1;
      byte b2;
      byte b3;
      byte b4;
      
      UintToBytes(uint u) { ... }
     };
    
    void put(uint w) 
     { 
      UintToBytes x=new UintToBytes(w); 
      
      put(x.b1); 
      put(x.b2); 
      put(x.b3); 
      put(x.b4); 
     }
   }


Естественно, в C# это не легально, и я вынужден заменить интерфейс абстрактным классом.

  abstract class IByteWriter
   {
    public abstract void put(byte b);
    
     struct UintToBytes
      {
       public byte b1;
       public byte b2;
       public byte b3;
       public byte b4;
      
       public UintToBytes(uint u) { ... }
      };
    
    public void put(uint w) 
     { 
      UintToBytes x=new UintToBytes(w); 
      
      put(x.b1); 
      put(x.b2); 
      put(x.b3); 
      put(x.b4); 
     }
   }


И тут я сталкиваюсь с проблеммой -- я могу унаследовать только от одного такого класса.
Если я в финальный класс захочу включить ещё один абстрактный базовый класс, например IStreamControl или IOutOfBandMessage, то у меня возникают траблы.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.06 12:34
Оценка: :))
Здравствуйте, Kluev, Вы писали:

K>Множественное наследование незаменимая вещь, юзаем по полной программе.

K>Реальный пример:
K>
K>class QS_Face
K>    : public QS_Object // базовый стафф
K>    , public ListNode2<QS_Face,QS_Shell>  // узел для интрузивного списка в классе Shell
K>    , public ListNode2<QS_Face,QS_Model>  // узел для интрузивного списка в классе Model
K>    , public SCX_Member // этот класс позволяет обьекту отображатся на 3д сцене, аггрегация не подходит т.к. перегружаются виртуальные функции
K>{
K>public:
K>   // понеслась
K>


Вы и запятые кверху задом юзайте. Это мало интересно. Интересны именно ситуации когда это дает приемущество перед другими подходами. То есть кокретные примеры и обоснования.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Множественное наследование, mix-in-ы, traits
От: WolfHound  
Дата: 10.05.06 18:24
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.

VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.
Однажды я делал свою реализацию контролов которая может отображаться и через WinForms и через WebForms и через черт знает что еще. Иерархия контролов состояла только из их интерфейсов. Реализация для каждой платформы была своя.
Так вот при реализации отображения дли WinForms нужно было реализовать кучу своейст и методов этих интерфейсов. Причем кроме конкретных интерфейсов были еще и общие интерфейсы для разных контролов так вот их реализация была идентична. Дело было на C#... Короче словил я на этой задаче кучу копипаста.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 11.05.06 10:04
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Шахтер, Вы писали:


VD>Ну, на конец то разумный пример без явных багов в проектировании. Реализация вспомогательных методов и частиченая реализация интерфейса — это хороший аргумент.


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




VD>Вот только в Nrmerle есть маросатрибут [Nemerle.DesignPatterns.ProxyAllMembers()] который, если я верно понимаю позволяет решить проблему автоматически созадав обертки над методами и делегировав их вызовы вложенному объекту.


Танцы с бубном? А если вложенный обьект имеет виртульные функции которые необходимо переопределить в верхнем классе?

Тогда через делегаты и ручками, или вложенный обьект + верхний наследуем от интерфейса, сссылку на интерфейс передаем во вложенный обьект. Костыли и грабли налицо.

Множественное наследование отлично справляется когда есть иерархия классов и к некоторым из них нужно подключать функциональность которая не обеспечена основной иерархией. Т.е. если основная иерархия заточена под манипуляцию с данными, к одним классам добавляем визуализацию, к другим, что-то другое. Интерфейсы здесь не подходят т.к в одном флаконе требуются данные и реализация. Естественно проектировать классы надо с учетом того что они могут быть использованы во множ-наследовании.
Re[9]: Множественное наследование, mix-in-ы, traits
От: WolfHound  
Дата: 12.05.06 22:06
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>А в чем копипэст если ты реализуешь интерфейс в наследнике?

В том что в нескольких наследниках приходится писать один и тотже код.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: "Узнаю тип, и узнаю калибр!" (c) Л. Буссенар
От: c-smile Канада http://terrainformatica.com
Дата: 13.05.06 06:45
Оценка: :))
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>PPS.: Есть только одна группа аргументов, которая перевешивает десятки мегабайт трафика таких дискуссий. Начинаются аргументы этой группы со слов: "Я хочу".


Из этой же серии :

Если ваша жена начинает фразу со слов "ты всегда" или "ты никогда" — знайте, дальше последует неправда.
(принцип работает на 100% — проверено)

И вообще: Ubi nil vales, ibi nil velis...
(это не я сказал)
Re: "Узнаю тип, и узнаю калибр!" (c) Л. Буссенар
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.06 09:08
Оценка: :))
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>И любой приводимый пример можно по такой схеме разнести в квантовую пыль, а значит,...


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

Так что если есть примеры, то милости просим, а если нет, то места для флуда хватает.

Что касается разнесения в пух и прах, то разношу я явно безграмотный дизайн. И обилие такового наводит меня на мысль, что заменители МН тоже будут порождать безграмотный дизайн. Понятно, что это зависит от поыта и знаний конкреных людей, но факт от этого фактом быть не перестает.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Множественное наследование, mix-in-ы, traits
От: WoldemaR Россия  
Дата: 15.05.06 06:01
Оценка: -1 :)
Здравствуйте, VladD2, Вы писали:

VD>Document не имеет быть права контролом (Widget-ом) с точки зрения дизайна, в прочем как и фигурой (Shape) и исполнителем действий (Executor).


Паттерн "точка сборки" может быть кем угодно и чем угодно. (с) WoldemaR. Ссылка при цитировании обязательна.


VD>И того при нормальном дизайте этот класс будет вглядеть как-то так:

VD>
VD>// Объект создаваемый фабрикой
VD>[ClassFabric(X)]
VD>class Document : SchemaNode
VD>{
VD>  Properties Properties { get { Properties(); } }
VD>}
VD>


А почему это SchemaNode? У меня в отчёте и диаграммы и графики и схемы и буквы и картинки и линии и полигоны и стрелочки и всё это комбинируется в произвольном порядке.


VD>Вывод — очередная демонстрация того как МН приводит к ужасному дизайну "гэть в кучу".


VD>Не... получился бы хороший дизайн намного более подходящий для дольнейшего развития.


Мне кажется ты просто ещё не сталкивался с задачами построения сильно гибридизированных редакторов.
Полиморфное разделение объектов графического редактора, которое демонстрируется в каждом учебнике по ООП — тупиковый путь. индустрия ( -какое слово то!!!) от него уже давно отказалась.

Если есть желание "въехать в тему" могу предложить в качестве домашнего задания продумать архитектуру классов "универсального интерактивного графического редактора". Минимальный функционал описан в моём первом сообщении.
Желаю творческих узбеков.
Re[4]: Множественное наследование, mix-in-ы, traits
От: A.Lokotkov Россия http://www.linkedin.com/pub/alexander-lokotkov/a/701/625
Дата: 16.05.06 03:36
Оценка: +1 :)
Здравствуйте, WoldemaR, Вы писали:

WR>Полиморфное разделение объектов графического редактора, которое демонстрируется в каждом учебнике по ООП — тупиковый путь. индустрия ( -какое слово то!!!) от него уже давно отказалась.


Не могли бы Вы привести ссылок на тему отказа индустрии от ПРО?
bloß it hudla
Re: Множественное наследование, mix-in-ы, traits
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.05.06 11:16
Оценка: 26 (1)
Здравствуйте, VladD2, Вы писали:

VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Например, иногда требовалось сделать объект одновременно Qt виджетом и SObjectizer
Автор: Евгений Охотников
Дата: 30.12.05
-агентом:
class    GEMONT_1_QT_WIDGET_TYPE    a_qt_widget_t
    :    public QWidget
    ,    public so_4::rt::agent_t
{
    Q_OBJECT

    //! Псевдоним базового типа.
    typedef so_4::rt::agent_t so_base_type_t;
...


Еще из недавнего. В Ruby есть unit-тест фреймворк, при использовании которого Unit-тесты нужно оформлять таким образом:
class TC_MyTestCase < Test::Unit::TestCase # Класс моего Unit-теста наследуется от специального.
  ... # реализация.
end

При разработке Mxx_ru
Автор: eao197
Дата: 09.04.06
оказалось, что в Unit-тестах, инициирующих компиляцию C++ кода дублируется слишком много одинакового кода. Поэтому сначала я захотел вынести этот код в отдельный базовый класс для Unit-тестов проверяющих компиляцию:
class TestWithCompilation < Test::Unit::TestCase
  ... # общий для всех код.
end

# Конкретный тест.
class TC_RuCodeGen < TestWithCompilation
  ... # реализация конкретного теста.
end

Но здесь обнаружились грабли: фреймоворк воспринимал всех наследников от TestCase как конкретные тесты и пытался их запускать. При попытке запуска TestWithCompilation ни одного test-метода не находилось и TestCase генерировал исключение. Чтобы обойти эту шнягу пришлось оформить TestWithCompilation в виде mixin-а и подмешивать его в конкретные классы тестов:
class TC_RuCodeGen < Test::Unit::TestCase
  include TestWithCompilation
  ... # реализация конкретного теста.
end


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Множественное наследование, mix-in-ы, traits
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.05.06 13:19
Оценка: 26 (1)
Здравствуйте, VladD2, Вы писали:

VD>Это по мне так пример плохого дизайна. Смешивание в однгом объекте бизнес-логики и презентационной логики.



Вообще-то ноги такого наследования растут из того, что в том же Qt (насколько я знаю и в wxWidgets, и в FOX) обращаться к GUI элементам (окнам, контролам) или рисовать на экране можно было только из главной нити приложения. Соответственно, задачка on-line отображения на экране информации, возникающей в недрах SObjectizer была не очень тривиальной. А это было приложение, которое в real-time (мягком) отображало мониторинговую информацию. Нужно было как-то организовывать взаимодействие между View-виджетом и работающими агентами. Что влекло за собой какую-то очередь (возможно не одну), синхронизацию, уведомления и пр. В то время как SObjectizer все это уже предоставлял в готовом виде. Так что в смешение QWidget и агента не было смешением бизнес-логики и презентации. Скорее это был способ создания презентации, способной в real-time воспринимать информацию от бизнес-логики. Гораздо более простой и дешевый способ, чем использование вспомогательных подпорок в виде дополнительных очередей сообщений.

VD>Получается, что оба примера — поимеры неверного проектирования других ошибок. Вот и я к тому же прихожу анализируя свой опыт.

VD>Вот и встает вопрос, а так ли действительно нжуно МН или его заменители?

Если мне не отшибает память, то Гради Буч о МН отзывался так:

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

(за точность цитаты не ручаюсь, нет книги под рукой).

Исходя из мнения Буча как раз можно ожидать, что МН будет использовано для обхода чьих-то (в большинстве случаев, однако, своих ) кривых решений.

Вот еще один пример (что называется из не написанного). У меня в Ruby есть класс Toolset, от которого должны создаваться наследники для адаптации к конкретным компиляторам (VcFamily, GccFamily, C89Family и пр.). Все было хорошо и складно до тех пор, пока не оказалось, что для Unix-платформ нужно поддержать специфическую функциональность: жесткое задание линкеру типа библиотеки (в Unix аргумент -lA может означать как линковку libA.a (статической библиотеки), так и libA.so (динамической библиотеки), а нужно было, чтобы -lA означал линковку строго libA.a). Соответственно, в toolset-ах, которые работают под Unix-ом появляется набор одинаковых методов и атрибутов, которые хорошо было бы вынести в общий класс. Могло бы показаться, что достаточно сделать от Toolset наследника UnixToolset, чтобы от UnixToolset уже наследовать классы для Unix-овых компиляторов. Однако, не все так просто. Для того же самого GCC есть порты под Windows (MinGW и в Cygwin). И как раз иерархию классов GccFamily разбавить UnixToolset-ом уже не просто. В этом случае проще выделить данную функциональность в какой-нибудь mixin UnixLibLinking и подмешивать его к Unix-овым toolset-ам, унаследованным от Toolset или каких-то родовых классов (вроде GccFamily или C89Family).

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Множественное наследование, mix-in-ы, traits
От: IT Россия linq2db.com
Дата: 10.05.06 21:24
Оценка: 26 (1)
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


1. Binding ASP.NET лучше всего работает с объектами, реализующими интерфейс ITypedList. Реализация этого интерфейса нетривиальна, но вполне возможна. Один раз реализовав TypedListImpl далее с помощью миксинов можно было бы подключать эту реализацию к нужным объектам. Сейчас это делается в базовом классе и с помощью копипейста переносится из проекта в проект.

2. При наличии соответствующих интерфейсов валидация тоже могла бы легко добавляться к объекту с помощью миксинов. Сейчас это делается так же в базовом классе.

3-й пример из той же серии — EditableObject. Причём, так как он всё равно работает только с абстрактными классами, а для них у нас уже есть реализация миксинов, то я в серьёз подумываю о том, чтобы прикрутить такую возможность к BLToolkit. Цель — высвободить базовый класс из пут фреймворка и оставить его в полном распоряжении разработчика.

4. Интерфейс IServiceProvider. Обычно каждый сервис реализует ещё и этот интерфейс, причём очень часто это простая делегация вызова к сервису, который зарегестрировал текущий сервис. Нужно реализовать всего лишь один метод, но с миксином было бы всё совсем просто.

VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Не знаю наколько это было бы резким упрощением. Чаще всего это делается один раз в базовом классе, а для резкого упрощения нужно искать часто решаемые однотипные задачи.
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Множественное наследование, mix-in-ы, traits
От: vdimas Россия  
Дата: 14.05.06 13:32
Оценка: 26 (1)
Здравствуйте, VladD2, Вы писали:

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


WH>>А как? Есть куча ВинФормсовских контролов. Каждый из которых должен реализовывать платформонезависимый интерфейс чтобы другие части системы могли работать независимо от того что именно ресует контролы. Скажем интерфейс IUIControl содержит порядка двух десятков элементов. А этот интерфейс должны реализовывать все видимые контролы.

WH>>Как тут обойтись без копипаста? Правильно миксины или множественное наследование реализации или макросы. Ни того ни другого ни третьего в C# нет.

VD>А в чем копипэст если ты реализуешь интерфейс в наследнике?


В том, что ты обогащаешь функциональностью уже имеющуюся иерархию, т.е. приходится обогащать каждый ее член. Причем, отсутствие MH действительно заставляет делать столько повторяющейся работы, что дешевле делать свою собственную иерархию, в которой инкапсулировать чужую. Т.е. свою иерархию неких MyControlBase. По крайней мере в моих экспериментах на эти же точно темы таким макаром получалось гораздо меньше "дурной" работы, несмотря на всякие тонкости с изменением структуры инкапсулируемой иерархии внешними воздействиями (т.е. возня с синхронизацией графов наших объектов и соотв инкапсулированных). Точно такие же задачи на С++ решались походя всего 1 раз, за счет МН и возможности указывать параметром шаблона тип, который будет в числе базовых.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Множественное наследование, mix-in-ы, traits
От: PhantomIvan  
Дата: 15.05.06 11:39
Оценка: 26 (1)
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Попробуем простейший пример из баз данных: Data Access Layer. Есть хранимые процедуры, и гейты (паттерн Gateway).

    public interface IGetGateway
    {
        DataRow GetSingle(int id);
        DataTable GetMultiple();
    }

Это для получения записи по ключу или всех записей.

    public interface IDeleteGateway
    {
        int Delete(int id);
    }

Это для удаления записи.

Теперь один из гейтов:
    public class PollGateway : GetGateway, IGetGateway, IDeleteGateway
    {
        private DeleteHelper deleteHelper;
        
        public PollGateway(SqlConnection connection) : base(connection, "cms_polls_get")
        {
            deleteHelper = new DeleteHelper(connection, "cms_polls_del");
        }
        ...
        public int Delete(int id)
        {
            return deleteHelper.Delete(id);
        }
    }


Понятно, что представляет собой GetGateway:
    public class GetGateway : Gateway, IGetGateway
    {
        private readonly string procedure;

        public GetGateway(SqlConnection connection, string getStoredProcedure) : base(connection)
        {
            procedure = getStoredProcedure;
        }

        public virtual DataRow GetSingle(int id)
        {
        ...
        }

        public virtual DataTable GetMultiple()
        {
        ...
        }
    }
}


Теперь внимание: добавляем в IDeleteGateway метод DeleteAll. Ну, вы догадались.
Кроме того, не в каждой таблице есть ключ, т.е. не каждый гейт должен реализовать IGetGateway. А некоторым гейтам запрещено удалять записи.
Конечно, хочется поддержки сабжа в языке. А там уж думать, использовать сабж или нет, а если да, то как это делать по уму.

P.S. traits-проект для C# здесь, при поддержке microsoft
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 11.05.06 02:21
Оценка: 14 (1)
Здравствуйте, VladD2, Вы писали:

VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Вот пример hello world из Harmonia:


Функциональность HtmlPanelT (html container) может
быть приделана к любому контейнеру виджетов:

Подмешивание методом curiously recurring template.

module samples.hello1;

// HTML Hello World.

import harmonia.ui.application;
import harmonia.ui.window;
import harmonia.html.view;

// HTML behavior can be attached to any container
// This time to the window.
alias HtmlPanelT!(Window) HtmlWindow;

void HelloWorldStart()
{
  HtmlWindow w = new HtmlWindow;
  w.html = 
     "<HTML back-color='edit info' 
            text-align=center 
            vertical-align=middle>Hello World!</HTML>";
  w.state = Window.STATE.NORMAL;
}

static this() 
{
  Application.onStart = &HelloWorldStart;
}


Второй пример опять же из Harmonia:

Здесь мы имеем классический пример когда на один класс
навешиваются различные свойства/имплементации из некоего конструктора.
Писать такое каждый раз — тоскливо.

В D нет множественного наследования (что есть хорошо)
поэтому mixin'ы естественный путь.


// Реализация свойства/состояния enabled 

template EnabledImpl()
{
  private bool _disabled;
  bool enabled() { return _disabled?false:true; }
  bool enabled(bool onoff) { _disabled = onoff?false:true; return enabled(); }
}


class EditBox: Widget, IValue, IInline, IProperties
{
public:
  mixin EnabledImpl!();
....
}

И еще куча widget derived классов


А это вот немного не в тему но тем не менее:
Это mixin выполняющий роль macro в С/С++,
в данном случае template traverser создает
локальную (inner) типизированную функцию traverseEvent


    // set the Widget in focus
    bool setFocus(Widget c, bool andCommandTarget = true)
    {
      mixin traverser!(EventWidget,Application.onEventWidget);

      if(c !is null)
      {
        _widgetEvent.type      = EventWidget.FOCUS_IN;
        if(!traverseEvent(_widgetEvent,c) || _widgetEvent.cancel)
          return false;
      }

      if(_focus !is null)
      {
        _widgetEvent.type      = EventWidget.FOCUS_OUT;
        if(!traverseEvent(_widgetEvent,_focus) || _widgetEvent.cancel) 
          return false;
      }
      return true;
    }


Ну и потом, какой крутой пацан без миксины?
Re[8]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 12.05.06 22:56
Оценка: 14 (1)
Здравствуйте, eao197, Вы писали:


E>Так может эта... Может глянуть что именно компилятор D в таком случае говорит? Может он говорит, что DisabledImpl не может быть подмешен к классу из-за того, что в классе нет _disabled, который нужен DisabledImpl?


E>Я не пользовался D, но есть подозрение, что подобную диагностику он должен нормально выдавать.


Так оно и есть — нормальное сообщение.

E>

E>Пользуясь случаем хочу задать вопрос c-smile о D (прошу прощения за оффтопик, по почте с c-smile у меня не получилось связаться ).

Как так?

E>Андрей, вообще видны какие нибудь перспективы появления стабильной версии языка? А то смотришь его ChangeLog -- все время что-то меняется. Да и в списке того, что хотелось иметь, еще есть пункты. Как то стремно связываться с языком и писать код с сознанием того, что после очередного изменения в языке часть кода придется переписывать.


Что тебе сказать.... Я пока не связываюсь. По этой самой причине.
Пришлось Harmonia править пару раз, правда не сильно если честно.

Мне лично нужен механизм аналогичный const в С++.
Без него как-то сложно большой проект запускать...
Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.05.06 18:34
Оценка: 6 (1)
Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.

Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Множественное наследование, mix-in-ы, traits
От: dshe  
Дата: 11.05.06 11:21
Оценка: 5 (1)
Здравствуйте, Kluev, Вы писали:

K>Множественное наследование отлично справляется когда есть иерархия классов и к некоторым из них нужно подключать функциональность которая не обеспечена основной иерархией. Т.е. если основная иерархия заточена под манипуляцию с данными, к одним классам добавляем визуализацию, к другим, что-то другое. Интерфейсы здесь не подходят т.к в одном флаконе требуются данные и реализация. Естественно проектировать классы надо с учетом того что они могут быть использованы во множ-наследовании.


Цели, ради которых и было придумано множественное наследование, вроде бы ясны. Однако, на мой взгляд множественное наследование реализации (по крайней мере в том виде, в каком оно реализовано в C++) чревато граблями больше, чем дает преимуществ. С МН возникает, так называемая, Diamond problem.
class A {};
class B: public A {};
class C: public A {};
class D: public B, public C {};

В приведенном примере объект класса D будет в себе содержать два экземпляра базового подобъекта класса A. Один унаследован от B, другой -- от C. иногда это бывает полезно, но иногда требуется только один базовый подобъект. В C++ это контролируется при помощи виртуального наследования.
class A {};
class B: public virtual A {};
class C: public virtual A {};
class D: public B, public C {};

В этом примере экземпляр класса D будет содержать только один базовый подобъект класса A.

Представим, что класс D (который наследуется от B, C) разрабатывает один разработчик и он понимает, что ему требуется иметь один подобъект класса A в D, т.е. ему необходимо виртуальное наследование. Вот тут возникает затык, поскольку ему необходимо будет менять классы B и C, а они могут разрабатываться другим разработчиком и эти классы могут поставляться без исходников. Т.е. разработчик классов B и C должен был бы заранее предусмотреть, что от них будут множественно наследоваться.

Следует также отметить, что для выражения отношения is-a стоило бы всегда использовать виртуальное наследование. Просто потому, что ну не может одна сущность являться другой несколько раз! Невиртуальное наследование отражает скорее отношение между классами has-a. Вот забавный пример, когда задумывалось множественное именно невиртуальное наследование.
class wheel {};
class first_wheel: public wheel {};
class second_wheel: public wheel {};
class third_wheel: public wheel {};
class fourth_wheel: public wheel {};
class vehicle: public first_wheel, public second_wheel, public third_wheel, public fourth_wheel {};

Здесь транспортное средство наследуется от четырех колес. Полагаю, что этот пример было бы более естественно переписать с использованием агрегации, а не наследования. Транспортное средство ведь не есть колесо четырежды, -- оно имеет четыре колеса.

Однако лично я редко видел, чтобы активно использовалось виртуальное наследование. По крайней в примерах кода в данном топике его по-моему не было ниразу. Должно быть, это из-за того, что виртуальное наследование бесплатно не дается и приведение к виртуальному базовому подобъекту менее эффективно, чем к невиртуальному. А может быть просто сила привычки.

Есть еще одна проблема с виртуальным наследованием: оно вынуждает классу знать не только о своих непосредственных предках, а и о всех своих виртуальных предках.
class A {
public:
    A(int) {}
};
class B: public virtual A {
public:
    B(): A(1) {}
};
class C: public virtual A {
public:
    C(): A(2) {}
};
class D: public B, public C {
public:
    D(): B(), C(), A(3) {}
};

При создании экземпляра класса D и инициализации единственного базового подобъекта A, какой конструктор должен Вызваться: A(1) или A(2)? Здесь решение принимается в классе D. Об этом можно не беспокоиться, если класс, унаследованный виртуально, имеет конструктор по умолчанию. Но в общем случае это добавляет лишние зависимости.

Резюмирую: для того, чтобы безопасно использовать МН в C++ необходимо чтобы у всех классов были конструкторы по умолчанию и все классы должны наследоваться виртуально. Мне кажется, что эти требования весьма жесткие.
--
Дмитро
Re[3]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 11.05.06 07:07
Оценка: 4 (1)
Здравствуйте, Anton V. Kolotaev, Вы писали:

AVK>Как решается средствами D проблема, когда примесям надо обращаться друг к другу?


AVK>Т.е. есть ли альтернатива следующему основанному на CRTP коду?


AVK>
AVK>template <class Derived>
AVK>    struct ImplA
AVK>{
AVK>    void f() { static_cast<Derived*>(this)->g(); }  
AVK>    void h();
AVK>};

AVK>template <class Derived>
AVK>    struct ImplB
AVK>{
AVK>    void g(); { static_cast<Derived*>(this)->h(); }
AVK>};

AVK>struct Component
AVK>    :  ImplA<Component>
AVK>    ,  ImplB<Component>
AVK>{};
AVK>



Норально решается. mixin's резолвятся во время последней фазы
компиляции. Поэтому такое вот работает:


template EnabledImpl()
{
  protected bool _disabled;
  bool enabled() { return _disabled?false:true; }
  bool enabled(bool onoff) { _disabled = onoff?false:true; return enabled(); }
}

template DisabledImpl()
{
  bool disabled() { return _disabled; }
  bool disabled(bool onoff) { _disabled = onoff; return disabled(); }
}


class EditBox: Widget, IValue, IInline, IProperties
{
public:
  mixin EnabledImpl!();
  mixin DisabledImpl!();

....
}
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.06 16:21
Оценка: 1 (1)
Здравствуйте, c-smile, Вы писали:

CS>Норально решается. mixin's резолвятся во время последней фазы

CS>компиляции. Поэтому такое вот работает:


CS>
CS>template DisabledImpl()
CS>{
CS>  bool disabled() { return _disabled; }
CS>  bool disabled(bool onoff) { _disabled = onoff; return disabled(); }
CS>}
CS>


То есть никакого контроля до использования, и в добавок прямое обращение к именам из внешних классов?

Мне кажется — это очень плохой дизайн. Ошибок будет много а и их поиск не прост.

В трэйтсах используемые из внешнего класса члены декларируются специальным образом, что снимает проблему. Но остается проблема разрешения конфликтов.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 12.05.06 23:05
Оценка: 1 (1)
Здравствуйте, dshe, Вы писали:

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


D>>Я здесь более акцентировал внимание на то, что у mixin'а лучше было бы иметь четко определенный контракт, который, в свою очередь, мог бы помочь обнаружить проблемы на более ранних стадиях компиляции и, возможно, с более понятной диагностикой.

D>+ (что не менее важно) помог бы программисту понять к чему можно применять данный mixin, а к чему нет, еще до того, как он получит ошибку компиляции.

Контракт это что? Фактически это описание параметров для мета функции...
Ну так и пишем в D


template DisabledImpl(alias disabledMember:bool = _disabled)
{
  bool disabled() { return disabledMember; }
  bool disabled(bool onoff) { disabledMember = onoff; return disabled(); }
}
Re: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 10.05.06 07:42
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Множественное наследование незаменимая вещь, юзаем по полной программе.
Реальный пример:
class QS_Face
    : public QS_Object // базовый стафф
    , public ListNode2<QS_Face,QS_Shell>  // узел для интрузивного списка в классе Shell
    , public ListNode2<QS_Face,QS_Model>  // узел для интрузивного списка в классе Model
    , public SCX_Member // этот класс позволяет обьекту отображатся на 3д сцене, аггрегация не подходит т.к. перегружаются виртуальные функции
{
public:
   // понеслась
Re[5]: Множественное наследование, mix-in-ы, traits
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.05.06 13:54
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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


Да, если рассматривать МН как способ преодоления проблем, то именно так и получается.


Но мне еще всгда казалось, что МН может быть хорошим приемом проектирования при необходимости объединения разнородной функциональности в одном месте. Для меня самым показательным примером является такая сущность, как "мнемосхема" в АСУТП: эта такая картинка с изображением технологического процесса, на которой в динамике отображаются показатели датчиков, состояние оборудования, какие-то наиболее важные сообщения и т.д. Т.е., с одной стороны -- это GUI объект (какой-нибудь widget, производный от соответствующего базового класса), с другой стороны -- это какой-то слушатель (наблюдатель). Здесь гораздо проще унаследоваться одновременно от нескольких базовых классов, чем использовать множественное наследование интерфейсов, а затем через агрегирование встраивать всю функциональность.

Т.е. МН может еще и служить средством борьбы с изначальной сложностью проблемы и/или жесткостью органичений на возможные решения.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Множественное наследование, mix-in-ы, traits
От: Anton V. Kolotaev  
Дата: 11.05.06 06:50
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Вот только в Nrmerle есть маросатрибут [Nemerle.DesignPatterns.ProxyAllMembers()] который, если я верно понимаю позволяет решить проблему автоматически созадав обертки над методами и делегировав их вызовы вложенному объекту.


Правда, если у нас нет развитой макросистемы, то мы тут же начинаем заниматься набиванием кода проксей. А если макросистема есть, то imho любую задачу, решаемую МН, можно решить и макросами. Разве что только это решение может иметь высокую плату за вход.
... << RSDN@Home 1.2.0 alpha rev. 648>>
Re[2]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.06 16:21
Оценка: +1
Здравствуйте, WoldemaR, Вы писали:

WR>Если выражаться общими словами, то можно сказать что множественное наследование рулит при описании ортогональной функциональности. Приведу пример из своей практики:

WR>
WR>class LIKEVIEW_API Document : // Класс - Точка сборки
WR>    public Object<LV_IDCLASS_DOCUMENT_BASE, Document>, // Объект создаваемый фабрикой
WR>    public RefCounter,    // счётчик ссылок
WR>    public Widget,        // базовый элемент ГУИ
WR>    public Properties,    // контейнер свойств
WR>    public Shape,         // фигура ГДИ
WR>    public IdGenerator,   // генератор идентификаторов для сериализации связей
WR>    public Port,          // узел графа схемы
WR>    public Link,          // связь графа схемы
WR>    public Executor       // исполнитель действий
WR>{
WR>// ...
WR>


RefCounter в лес за недадобностью.
Document не имеет быть права контролом (Widget-ом) с точки зрения дизайна, в прочем как и фигурой (Shape) и исполнителем действий (Executor).
И того при нормальном дизайте этот класс будет вглядеть как-то так:
// Объект создаваемый фабрикой
[ClassFabric(X)]
class Document : SchemaNode
{
  Properties Properties { get { Properties(); } }
}


Вывод — очередная демонстрация того как МН приводит к ужасному дизайну "гэть в кучу".

WR>В данном примере показано наследование для основного класса Document библиотеки LikeView.

WR>Библиотека предназначена для построения интерактивных 2D графических приложений, представляет собой архитектурный каркас и расширяемый набор действий-утилит. На ней можно с одинаковым успехом писать векторные редакторы, редакторы схем, диаграмм и пользовательский интерфейс.

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


Не... получился бы хороший дизайн намного более подходящий для дольнейшего развития.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 11.05.06 16:44
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, c-smile, Вы писали:


CS>>Норально решается. mixin's резолвятся во время последней фазы

CS>>компиляции. Поэтому такое вот работает:


CS>>
CS>>template DisabledImpl()
CS>>{
CS>>  bool disabled() { return _disabled; }
CS>>  bool disabled(bool onoff) { _disabled = onoff; return disabled(); }
CS>>}
CS>>


VD>То есть никакого контроля до использования, и в добавок прямое обращение к именам из внешних классов?


mixin ( template собственно ) не есть класс. Это частичный фрагмент имплементации.
Понятия "внешних классов" для template нет — есть "точка приложения" или место вставки
со своим окружением и т.д.

Данная DisabledImpl() в том виде как объявлена может быть применена
к чему либо имеющему _disabled переменную в области применения.

Иначе — ошибка компиляции.

VD>Мне кажется — это очень плохой дизайн. Ошибок будет много а и их поиск не прост.


А мне нет.

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


static if есть для этого случая в D — проверка типов и условий использования.
Re[6]: Множественное наследование, mix-in-ы, traits
От: dshe  
Дата: 12.05.06 09:00
Оценка: +1
Здравствуйте, c-smile, Вы писали:

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


VD>>Здравствуйте, c-smile, Вы писали:


CS>>>Норально решается. mixin's резолвятся во время последней фазы

CS>>>компиляции. Поэтому такое вот работает:

VD>>То есть никакого контроля до использования, и в добавок прямое обращение к именам из внешних классов?


CS>Данная DisabledImpl() в том виде как объявлена может быть применена

CS>к чему либо имеющему _disabled переменную в области применения.

CS>Иначе — ошибка компиляции.


Так вот применишь ты, например, mixin DisabledImpl к чему-то, что не имеет переменной _disabled и будешь гадать, отчего же компиляция свалилась. DisabledImpl ведь к своему окружению особые требования предъявляет, только вот требования эти не локализованы, а размазаны по коду. Моменты и места, где обнаруживаются ошибки компиляции не равнозначны: я бы предпочел увидеть ошибку компиляции в месте, где DisabledImpl к чему-то применяется с сообщением, что mixin нельзя к этому применить, чем сообщение о том, что некая переменная _disabled (непонятно зачем нужная) не была найдена в DisabledImpl.
--
Дмитро
Re[8]: Множественное наследование, mix-in-ы, traits
От: dshe  
Дата: 12.05.06 09:25
Оценка: +1
Здравствуйте, eao197, Вы писали:

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


CS>>>Данная DisabledImpl() в том виде как объявлена может быть применена

CS>>>к чему либо имеющему _disabled переменную в области применения.

CS>>>Иначе — ошибка компиляции.


D>>Так вот применишь ты, например, mixin DisabledImpl к чему-то, что не имеет переменной _disabled и будешь гадать, отчего же компиляция свалилась. DisabledImpl ведь к своему окружению особые требования предъявляет, только вот требования эти не локализованы, а размазаны по коду. Моменты и места, где обнаруживаются ошибки компиляции не равнозначны: я бы предпочел увидеть ошибку компиляции в месте, где DisabledImpl к чему-то применяется с сообщением, что mixin нельзя к этому применить, чем сообщение о том, что некая переменная _disabled (непонятно зачем нужная) не была найдена в DisabledImpl.


E>Так может эта... Может глянуть что именно компилятор D в таком случае говорит? Может он говорит, что DisabledImpl не может быть подмешен к классу из-за того, что в классе нет _disabled, который нужен DisabledImpl?


E>Я не пользовался D, но есть подозрение, что подобную диагностику он должен нормально выдавать.


Я здесь более акцентировал внимание на то, что у mixin'а лучше было бы иметь четко определенный контракт, который, в свою очередь, мог бы помочь обнаружить проблемы на более ранних стадиях компиляции и, возможно, с более понятной диагностикой.
--
Дмитро
Re[9]: Множественное наследование, mix-in-ы, traits
От: dshe  
Дата: 12.05.06 09:32
Оценка: +1
Здравствуйте, dshe, Вы писали:

D>Я здесь более акцентировал внимание на то, что у mixin'а лучше было бы иметь четко определенный контракт, который, в свою очередь, мог бы помочь обнаружить проблемы на более ранних стадиях компиляции и, возможно, с более понятной диагностикой.

+ (что не менее важно) помог бы программисту понять к чему можно применять данный mixin, а к чему нет, еще до того, как он получит ошибку компиляции.
--
Дмитро
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.05.06 20:51
Оценка: :)
Здравствуйте, Kluev, Вы писали:

K>Ну, VladD2, как всегда самый умный и видимо самый красивый.


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

K> Давайте разбирать полеты без пристрастия.


Какие пристрастия? Вижу грязь — говорю "грязь".

K> Какие мы видим грабли в приведенном примере:


Грабли? Граблей здесь так много, что на них можно убить слишком много времени. А ошибки дизайна я уже описал. Каждая из них породит массу граблей в будущем.

Сеня в смех тянет когда я вижу документоэелемнографоузелоконтролоэкзекьютор, то говорить о каких то там мелочах вроде свойст уже нет никакого желания.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.05.06 20:51
Оценка: :)
Здравствуйте, Kluev, Вы писали:

K>А это пример значит неконкретный?


Это вообще не пример. Пример подразумевает объяснение целей и решений. Здесь же не ясно что и зачем.

K>Пример вполне тривиальный и жизненный. Грубо говоря обьект разделяется м-ду двумя документами. Один — модель, владелец всех обьектов, через которую идет вся работа с данными, другой документ 3-д сцены,


О как. Мы противопоставляем модль и документ. А что же тогда такое документ как не модель?

K> который юзается для отрисовки и UI манипуляций. т.е. не классичесский doc — view, а doc — proxy_doc — view. Где doc — модель, proxy_doc — сцена3д, view — окно_сцены.


Нда. Эту уже на концептуальном уровне выглядит страшно. Раньше все было просо "модель-представление-контроллер". Как разновидность интеграция контроллера в представление. Прокси использовался для создания переходника интерфейса. А тут прям новые концепции. Вот только один вопрос. А оно надо?

K> Преимущества такого подхода очевидны.


Кому, простите?

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


Ясно. А может вы просто про контроллер забыли?

K> Если бы вид одевался бы непосредственно на модель,


Что?

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


Ну, вот мы и пришли к странному дизайну.

В общем, чем дальше читаю эту тему, тем больше понимаю, что проблем от МН больше чем приемуществ. А ведь еще не давно я так не думал.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.05.06 20:51
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

WH>А как? Есть куча ВинФормсовских контролов. Каждый из которых должен реализовывать платформонезависимый интерфейс чтобы другие части системы могли работать независимо от того что именно ресует контролы. Скажем интерфейс IUIControl содержит порядка двух десятков элементов. А этот интерфейс должны реализовывать все видимые контролы.

WH>Как тут обойтись без копипаста? Правильно миксины или множественное наследование реализации или макросы. Ни того ни другого ни третьего в C# нет.

А в чем копипэст если ты реализуешь интерфейс в наследнике?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Та-а-акс...
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 13.05.06 02:31
Оценка: -1
Здравствуйте, VladD2, Вы писали:

WR>>Если выражаться общими словами, то можно сказать что множественное наследование рулит при описании ортогональной функциональности. Приведу пример из своей практики:

WR>>
WR>>class LIKEVIEW_API Document : // Класс - Точка сборки
WR>>    public Object<LV_IDCLASS_DOCUMENT_BASE, Document>, // Объект создаваемый фабрикой
WR>>    public RefCounter,    // счётчик ссылок
WR>>    public Widget,        // базовый элемент ГУИ
WR>>    public Properties,    // контейнер свойств
WR>>    public Shape,         // фигура ГДИ
WR>>    public IdGenerator,   // генератор идентификаторов для сериализации связей
WR>>    public Port,          // узел графа схемы
WR>>    public Link,          // связь графа схемы
WR>>    public Executor       // исполнитель действий
WR>>{
WR>>// ...
WR>>


VD>RefCounter в лес за недадобностью.


Осторожнее на виражах. RefCounter может быть нужен совсем не только для контроля жизненного цикла объекта. Могут быть и "сугубо прикладные" задачи. Например, оптимизация подсчётов для связей m:n.

Ergo. RefCounter — вернуть. Кстати, он может быть на-а-амного сложнее, чем банальный m_refs++/m_ref--. Ещё похожий пример с наследованием от узлов списков здесь приводили.

VD>Document не имеет быть права контролом (Widget-ом) с точки зрения дизайна, в прочем как и фигурой (Shape) и исполнителем действий (Executor).


Голословно. Документ имеет полное право быть кем угодно. Всё зависит от дальнейшего использования этого класса. Если большого количества наследников у него не предвидится, то и смешивать можно что угодно и как угодно. Никаких проблем это не даёт.

Короче, на основании чего ты делаешь такие безапелляционные выводы? Сформулируй критерии, по которым ты оцениваешь "наличие права быть тем-то и тем-то" в данном контексте.

VD>И того при нормальном дизайте этот класс будет вглядеть как-то так:


Э... осталось добавить вакуум и сферообразие.

VD>
VD>// Объект создаваемый фабрикой
VD>[ClassFabric(X)]
VD>class Document : SchemaNode
VD>{
VD>  Properties Properties { get { Properties(); } }
VD>}
VD>


VD>Вывод — очередная демонстрация того как МН приводит к ужасному дизайну "гэть в кучу".


Вывод о поспешно сделанном выводе ещё более очевиден.

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

VD>Не... получился бы хороший дизайн намного более подходящий для дольнейшего развития.

WoldemaR совершенно прав по поводу комбинаторного взрыва при исходной полиморфной декомпозиции. Тому косвенным подтверждением нагромождение коллекций в Java. Второе подтверждение — многократно осуждавшийся паттерн Visitor/Visited.
... << RSDN@Home 1.2.0 alpha rev. 643>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[10]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 13.05.06 06:29
Оценка: +1
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, c-smile, Вы писали:


E>>>Пользуясь случаем хочу задать вопрос c-smile о D (прошу прощения за оффтопик, по почте с c-smile у меня не получилось связаться ).


CS>>Как так?


E>Да где-то месяц-полтора назад отправлял тебе пару сообщений и через RSDN и на e-mail в твоем профиле, но ответа не получил

E>Ну да спрашивал я у тебя там то же самое, что и сейчас. Так что ответ, в конце-концов, получил

Можешь сегодня/завтра послать письмо?

У меня этот адрес public, на него стоко всякого сыпется ... запросто могу выплеснуть чего-нить полезное.
Извиняюсь если что. Если не отвечаю — пошлите письмо еще раз please.

Кстати со спамом надо что-то делать. e-mail как система загибается, имхо.

Особенно тоскливо получать спам с mail.ru... За державу и культуру обидно право слово.

Кстати все public mail сервера России в глубоком бане на форуме http://www.terrainformatica.com/bb/index.php.
Пожалуйста используйте другие какие-нибудь адреса для регистрации.
Извиняюсь, но просто нет времени это г. разгребать.
Re[7]: Множественное наследование, mix-in-ы, traits
От: WoldemaR Россия  
Дата: 17.05.06 10:53
Оценка: :)
Здравствуйте, DarkGray, Вы писали:

DG>Но ведь может быть и такой код:

DG>
DG>Figure obj = new Circle();
DG>obj = obj.ConvertTo<Square>();
DG>


Несмотря на то, что мазохизм иногда встречается в самых неожиданных формах, это не является поводом принимать извращения за правило.
Re[10]: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 19.05.06 11:33
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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


DG>>А четко обосновать почему это так, сможете? или только можете общие фразы выдавать?


VD>Ты не понял. Он же сказал "индустрия уже отказалась". Просто она сказала это толко ему одному. А мы просто еще не в крусе.


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

Даже полный успех в чужой дхарме бесполезен — к своей устремляйся (Бхагават Гита)

К тому же далеко не всегда индустрия шагает верным путем. Взять к примеру ХМЛ, средняя буква означает маркап, т.е. для разметки предназначен. Но досадному недоразумению ХМЛ стали юзать везде, причем как обычно в самых извращенных формах.
Re: Множественное наследование, mix-in-ы, traits
От: Oyster Украина https://github.com/devoyster
Дата: 09.05.06 19:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Последние примеры из жизни (очень маленькие, но всё же):

Пример #1

У нас в системе есть базовый класс исключения, возникающего при нарушении бизнес-правила — пусть это будет BizRuleViolationException. Где-то в UI стоит обработчик, который ловит все исключения, унаследованные от данного.

Мы также используем NHibernate, у которого есть исключение с забавным названием ValidationFailure. Мы в своих объектах обязаны кидать исключение именно такого (или производного) типа, если известно, что объект невалиден перед операцией сохранения в БД (интерфейс IValidatable).

Наше исключение, производное от ValidationFailure, содержит список поломанных правил и прочую полезную информацию. В то же время у нас есть механизм, преобразующий NHibernate-specific исключения в наши собственные, унаследованные от BizRuleViolationException (так всем проще). Как итог у нас есть два исключения-близнеца, унаследованные от разных базовых исключений, но содержащие один и тот же список поломанных правил и т.д. Тут бы я от traits или чего-то такого не отказался бы.

Пример #2

Во всё том же проекте есть бизнес-объекты и коллекции. И есть необходимость запускать некий код перед/после операций с базами данных. Как результат, базовый класс бизнес-объекта и базовый класс коллекции имеют набор методов вроде OnBeforeInsert/OnAfterInsert/... и соответствующих свойств. А один базовый класс тут невозможен потому, что коллекция, ясен пень, унаследована от List<T>.
Re: Множественное наследование, mix-in-ы, traits
От: iZEN СССР  
Дата: 09.05.06 19:41
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.

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

(От себя замечу: техника mixins лучше множественного наследования.)
Re[2]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.05.06 20:01
Оценка:
Здравствуйте, iZEN, Вы писали:

ZEN>(От себя замечу: техника mixins лучше множественного наследования.)


Меня не интересует что из перчисленного лучше. Меня интересуют области применения и польза.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Множественное наследование, mix-in-ы, traits
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 10.05.06 06:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Меня не интересует что из перчисленного лучше. Меня интересуют области применения и польза.


Да та же, что и от любого другого наследования реализации.
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.06 06:51
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Да та же, что и от любого другого наследования реализации.


Это общие слова, и интересуют конкретные примеры и аргументация.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Множественное наследование, mix-in-ы, traits
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 10.05.06 06:55
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это общие слова, и интересуют конкретные примеры и аргументация.


Блин, Влад, ты прикалуешся? Никогда никогда наследование не использовал?
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[6]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.06 12:34
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Блин, Влад, ты прикалуешся? Никогда никогда наследование не использовал?


Я не прикалываюсь. Мне интересны разные мнения.

Раньше я часто пользовался МН так как в ATL-е это был принятый паттерн наширения. Но перейдя на C# я со временем понял, что нужды в МН не испытываю. Возможно задачи такие были. Вот и интересны другие примеры.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.06 12:34
Оценка:
Здравствуйте, eao197, Вы писали:

Ну, наконец-то один ответ по теме! Уже за это хочется поставить оценку!

E>Например, иногда требовалось сделать объект одновременно Qt виджетом и SObjectizer
Автор: Евгений Охотников
Дата: 30.12.05
-агентом:

E>
E>class    GEMONT_1_QT_WIDGET_TYPE    a_qt_widget_t
E>    :    public QWidget
E>    ,    public so_4::rt::agent_t
E>{
E>    Q_OBJECT

E>    //! Псевдоним базового типа.
E>    typedef so_4::rt::agent_t so_base_type_t;
E>...
E>


Это по мне так пример плохого дизайна. Смешивание в однгом объекте бизнес-логики и презентационной логики.

E>...Но здесь обнаружились грабли: фреймоворк воспринимал всех наследников от TestCase как конкретные тесты и пытался их запускать...


То есть на лицо неграмотно спроектированный фрэймворк? В NUnit и MS-ых юнит-тестах подобных проблем нет, и МН не требуется.

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

Вот и встает вопрос, а так ли действительно нжуно МН или его заменители?

Хотелось бы найти пример в коотором МН или его заменители давли бы действительно ощутимое приемущество и сама задача при этом не была бы вызвана ошибочным дизайном.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Множественное наследование, mix-in-ы, traits
От: dshe  
Дата: 10.05.06 13:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это по мне так пример плохого дизайна. Смешивание в однгом объекте бизнес-логики и презентационной логики.


E>>...Но здесь обнаружились грабли: фреймоворк воспринимал всех наследников от TestCase как конкретные тесты и пытался их запускать...


VD>То есть на лицо неграмотно спроектированный фрэймворк? В NUnit и MS-ых юнит-тестах подобных проблем нет, и МН не требуется.


VD>Получается, что оба примера — поимеры неверного проектирования других ошибок. Вот и я к тому же прихожу анализируя свой опыт.


VD>Вот и встает вопрос, а так ли действительно нжуно МН или его заменители?


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

Мне кажется, что у тебя не возникало желания использовать МН не потому, что оно помогло бы решить задачу проще и лучше, а потому что ты "думал на С#" и, соответсвенно, подсознительно исключал для себя возможность использования МН. Те, кто "думает на C++", видят эти возможности чаще и не считают это признаком плохого дизайна.
--
Дмитро
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.06 13:41
Оценка:
Здравствуйте, dshe, Вы писали:

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


Отнюдь. Плевать мне на чужой дизайн. Меня интересует аргументация.

D>Мне кажется, что у тебя не возникало желания использовать МН не потому, что оно помогло бы решить задачу проще и лучше, а потому что ты "думал на С#" и, соответсвенно, подсознительно исключал для себя возможность использования МН.


Я думаю по-русски. И ничего не исключаю. Понято, что когда я пишу на C#, то отметаю эту возможность. Но при этом я испытываю, или не испытываю дискомфорт дискомфорт от этого. Вот я и заметил, что в общем-то не могут припомнить ни одного случая дискомфорта.

D> Те, кто "думает на C++", видят эти возможности чаще и не считают это признаком плохого дизайна.


Я писал на С++ не мало и не мало использовал то, без чего потом обходился без малейшего сожаления.

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

Дело в том, что вчера мне потребовалось обосновать необходимость traits в Nemerle:
http://nemerle.org/forum/viewtopic.php?t=244&amp;sid=533a4646e8a58584c5dee21a456b355e
и я задумался над аргументацией. Задумался, и понял, что ее в общем то у меня пока нет. Вот и решил получить помощь. Однако пока что никто ничего умного не сказал.
Вот я и думаю, не является ли МН и его заменители эдакой показной фичей которая реально на фиг не упала, но так как в языке Х она есть, то и нам надо заиметь?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.06 13:41
Оценка:
Здравствуйте, eao197, Вы писали:

Если подитожить, то получается что МН и т.п. незаменимы когда нужно обходить проблемы вызванные некорректным дизайном. И если свой дизайн можно изменить, то в случае с чужим дизайном мы имеем депйствительно трудно разрешимую пролему которая относительно хорошо решается подключением готовой реализации к имеющемуся классу. Так?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 10.05.06 15:17
Оценка:
Здравствуйте, VladD2, Вы писали:

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


K>>Множественное наследование незаменимая вещь, юзаем по полной программе.

K>>Реальный пример:
K>>
K>>class QS_Face
K>>    : public QS_Object // базовый стафф
K>>    , public ListNode2<QS_Face,QS_Shell>  // узел для интрузивного списка в классе Shell
K>>    , public ListNode2<QS_Face,QS_Model>  // узел для интрузивного списка в классе Model
K>>    , public SCX_Member // этот класс позволяет обьекту отображатся на 3д сцене, аггрегация не подходит т.к. перегружаются виртуальные функции
K>>{
K>>public:
K>>   // понеслась
K>>


VD>Вы и запятые кверху задом юзайте. Это мало интересно. Интересны именно ситуации когда это дает приемущество перед другими подходами. То есть кокретные примеры и обоснования.


А это пример значит неконкретный?

Пример вполне тривиальный и жизненный. Грубо говоря обьект разделяется м-ду двумя документами. Один — модель, владелец всех обьектов, через которую идет вся работа с данными, другой документ 3-д сцены, который юзается для отрисовки и UI манипуляций. т.е. не классичесский doc — view, а doc — proxy_doc — view. Где doc — модель, proxy_doc — сцена3д, view — окно_сцены. Преимущества такого подхода очевидны. Модель — крайне ветвиста и наворочена, в то время как на сцене может отображатся фактически только три примитива точка, линия и поверхность из треугольников. Взаимодействие с юзером, а именно просмотр и выбор обьектов мышкой идет через окно сцены. Если бы вид одевался бы непосредственно на модель, то это было бы крайне неэффективно т.к. пришлось бы работать с кучей разных типов, которые к тому же быстро эволюционируют в процессе разработки. Выход создание промежуточного документа, и множественное наследование используется чтобы сделать обьект участником двух документов одновременно: QS_Object — обязательный класс для всех обьектов модели, а если я хочу его бросить на сцену, то дополнительно юзаю SCX_Member. Без множ. наследования пришлось бы делать SCX_Member частью обьекта, а вместо виртуальных функций делать делегаты. Кривизна на лицо. Делать SCX_Member интерфейсом — тоже непрокатит, т.к. в нем немалый кусок реализации. Грубо говоря работа идет так: Делаем класс модели участником сцены (наследуемся от SCX_Member) далее через в процессе работы через SCX_Member добавляем на сцену конкретные обьекты (кривые, точки, поверхности). Когда данные обьекта модели становятся невалидными в SCX_Member ставится флаг dirty. Когда закончены все back-end операции и пришло время рисовать, для нужных обьектов (dirty==true) вызывается SCX_Member::regen (пересоздаем представление обьекта).
Это простой и естественный пример когда мн-наследование уместно и без него имеем грабли. Остальные подходы (типа аггрегации и делегирования) работают, но не так просто и красиво как мн-наследование.
Re[4]: Множественное наследование, mix-in-ы, traits
От: iZEN СССР  
Дата: 10.05.06 17:41
Оценка:
Здравствуйте, Kluev, Вы писали:


K>Пример вполне тривиальный и жизненный. Грубо говоря обьект разделяется м-ду двумя документами. Один — модель, владелец всех обьектов, через которую идет вся работа с данными, другой документ 3-д сцены, который юзается для отрисовки и UI манипуляций. т.е. не классичесский doc — view, а doc — proxy_doc — view. Где doc — модель, proxy_doc — сцена3д, view — окно_сцены. Преимущества такого подхода очевидны. Модель — крайне ветвиста и наворочена, в то время как на сцене может отображатся фактически только три примитива точка, линия и поверхность из треугольников. Взаимодействие с юзером, а именно просмотр и выбор обьектов мышкой идет через окно сцены. Если бы вид одевался бы непосредственно на модель, то это было бы крайне неэффективно т.к. пришлось бы работать с кучей разных типов, которые к тому же быстро эволюционируют в процессе разработки. Выход создание промежуточного документа, и множественное наследование используется чтобы сделать обьект участником двух документов одновременно: QS_Object — обязательный класс для всех обьектов модели, а если я хочу его бросить на сцену, то дополнительно юзаю SCX_Member. Без множ. наследования пришлось бы делать SCX_Member частью обьекта, а вместо виртуальных функций делать делегаты. Кривизна на лицо. Делать SCX_Member интерфейсом — тоже непрокатит, т.к. в нем немалый кусок реализации. Грубо говоря работа идет так: Делаем класс модели участником сцены (наследуемся от SCX_Member) далее через в процессе работы через SCX_Member добавляем на сцену конкретные обьекты (кривые, точки, поверхности). Когда данные обьекта модели становятся невалидными в SCX_Member ставится флаг dirty. Когда закончены все back-end операции и пришло время рисовать, для нужных обьектов (dirty==true) вызывается SCX_Member::regen (пересоздаем представление обьекта).

K>Это простой и естественный пример когда мн-наследование уместно и без него имеем грабли. Остальные подходы (типа аггрегации и делегирования) работают, но не так просто и красиво как мн-наследование.

У меня похожий образец UI в Java, но я обошёлся агрегированием вместо множественного наследования.
Есть view — канва, на которой отображаются виджеты.
Есть proxy_doc — синглетон-контейнер для однотипнах объектов-моделей — doc'ов в вашей терминологии.
proxy_doc ничего не известно о конкретной моделе, но известно об области канвы; он может только правильно отрисовать модель, нуждающуюся в отрисовке (реконструировать dirty_doc, заодно "превратив" их обратно в doc ).

Основной момент в таком образце: резко сокращаются накладные расходы на перерисовку всей сцены. Затрагивается только то, что действительно нуждается в обновлении. "Лишние" требования моделей на перерисовку себя отсекаются в proxy_doc и не приходят к view.
Re[5]: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 10.05.06 18:25
Оценка:
Здравствуйте, iZEN, Вы писали:

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


ZEN>У меня похожий образец UI в Java, но я обошёлся агрегированием вместо множественного наследования.

ZEN>Есть view — канва, на которой отображаются виджеты.
ZEN>Есть proxy_doc — синглетон-контейнер для однотипнах объектов-моделей — doc'ов в вашей терминологии.
ZEN>proxy_doc ничего не известно о конкретной моделе, но известно об области канвы; он может только правильно отрисовать модель, нуждающуюся в отрисовке (реконструировать dirty_doc, заодно "превратив" их обратно в doc ).

ZEN>Основной момент в таком образце: резко сокращаются накладные расходы на перерисовку всей сцены. Затрагивается только то, что действительно нуждается в обновлении. "Лишние" требования моделей на перерисовку себя отсекаются в proxy_doc и не приходят к view.


Я согласен что можно обойтись аггрегированием. А вместо вирутальных функций юзать делегаты. Или аггрегирование + наследование от интерфейса. Но это только workaround-ы, м-н подходит лучше.
Re[2]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.06 06:38
Оценка:
Здравствуйте, WolfHound, Вы писали:

Ты мог бы сформировать простой и наглядный пример?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.06 06:38
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ну, на конец то разумный пример без явных багов в проектировании. Реализация вспомогательных методов и частиченая реализация интерфейса — это хороший аргумент.
Отаровенно говоря мне за последние 5 лет такого не попадалось, но все же.

Вот только в Nrmerle есть маросатрибут [Nemerle.DesignPatterns.ProxyAllMembers()] который, если я верно понимаю позволяет решить проблему автоматически созадав обертки над методами и делегировав их вызовы вложенному объекту.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Множественное наследование, mix-in-ы, traits
От: Anton V. Kolotaev  
Дата: 11.05.06 06:39
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>В D нет множественного наследования (что есть хорошо)

CS>поэтому mixin'ы естественный путь.

CS>

CS>// Реализация свойства/состояния enabled 

CS>template EnabledImpl()
CS>{
CS>  private bool _disabled;
CS>  bool enabled() { return _disabled?false:true; }
CS>  bool enabled(bool onoff) { _disabled = onoff?false:true; return enabled(); }
CS>}


CS>class EditBox: Widget, IValue, IInline, IProperties
CS>{
CS>public:
CS>  mixin EnabledImpl!();
CS>....
CS>}

CS>И еще куча widget derived классов 

CS>


Как решается средствами D проблема, когда примесям надо обращаться друг к другу?

Т.е. есть ли альтернатива следующему основанному на CRTP коду?

template <class Derived>
    struct ImplA
{
    void f() { static_cast<Derived*>(this)->g(); }  
    void h();
};

template <class Derived>
    struct ImplB
{
    void g(); { static_cast<Derived*>(this)->h(); }
};

struct Component
    :  ImplA<Component>
    ,  ImplB<Component>
{};
... << RSDN@Home 1.2.0 alpha rev. 648>>
Re[4]: Множественное наследование, mix-in-ы, traits
От: Anton V. Kolotaev  
Дата: 11.05.06 07:17
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Норально решается. mixin's резолвятся во время последней фазы

CS>компиляции. Поэтому такое вот работает:


CS>
CS>template EnabledImpl()
CS>{
CS>  protected bool _disabled;
CS>  bool enabled() { return _disabled?false:true; }
CS>  bool enabled(bool onoff) { _disabled = onoff?false:true; return enabled(); }
CS>}
CS>


Если в конечном классе не будет члена _disabled, то в определении методов enabled имя _disabled свяжется лексически? Или будет ошибка?
... << RSDN@Home 1.2.0 alpha rev. 648>>
Re[2]: Множественное наследование, mix-in-ы, traits
От: _FRED_ Черногория
Дата: 11.05.06 07:56
Оценка:
Здравствуйте, Oyster, Вы писали:

O>Пример #2

O>…А один базовый класс тут невозможен потому, что коллекция, ясен пень, унаследована от List<T>.

А зачем List<T> не предназначен для наследования. Для создания собственных коллекций с контролируемым поведением есть Collection<T>. В крайнем случае — собственноручная реализация IList<T>+IList.
... << RSDN@Home 1.2.0 alpha rev. 650>>
Now playing: «Тихо в лесу…»
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Множественное наследование, mix-in-ы, traits
От: Oyster Украина https://github.com/devoyster
Дата: 11.05.06 08:02
Оценка:
Здравствуйте, _FRED_, Вы писали:

O>>Пример #2

O>>…А один базовый класс тут невозможен потому, что коллекция, ясен пень, унаследована от List<T>.

_FR>А зачем List<T> не предназначен для наследования. Для создания собственных коллекций с контролируемым поведением есть Collection<T>. В крайнем случае — собственноручная реализация IList<T>+IList.


Ну ладно — не List<T> (это я всех обманул ), а наш класс для списков... сути не меняет.
Re: Множественное наследование, mix-in-ы, traits
От: WoldemaR Россия  
Дата: 11.05.06 09:06
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Если выражаться общими словами, то можно сказать что множественное наследование рулит при описании ортогональной функциональности. Приведу пример из своей практики:
class LIKEVIEW_API Document : // Класс - Точка сборки
    public Object<LV_IDCLASS_DOCUMENT_BASE, Document>, // Объект создаваемый фабрикой
    public RefCounter,    // счётчик ссылок
    public Widget,        // базовый элемент ГУИ
    public Properties,    // контейнер свойств
    public Shape,         // фигура ГДИ
    public IdGenerator,   // генератор идентификаторов для сериализации связей
    public Port,          // узел графа схемы
    public Link,          // связь графа схемы
    public Executor       // исполнитель действий
{
// ...


В данном примере показано наследование для основного класса Document библиотеки LikeView.
Библиотека предназначена для построения интерактивных 2D графических приложений, представляет собой архитектурный каркас и расширяемый набор действий-утилит. На ней можно с одинаковым успехом писать векторные редакторы, редакторы схем, диаграмм и пользовательский интерфейс.

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

Таким образом по эффективности множественное наследование можно сравнить с операцией умножения.

А любители агрегирования получат тонны формального кода.

Предупреждаю об одном нехорошем свойстве данной архитектуры — это непредсказуемость.
Re[3]: Множественное наследование, mix-in-ы, traits
От: migel  
Дата: 11.05.06 16:13
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>Ты мог бы сформировать простой и наглядный пример?

Зыыыыыы
    public interface IControl
    {
        #region General Properies
        /// <summary>
        /// Нечто, присоедененное к элементу управления
        /// </summary>
        [ReflectedDependency]
        [Browsable(false)]
        object Tag
        {get;set;}
        #endregion

        #region Information Properties
        #endregion
    }    
    public interface IButton : IControl
    {
        string Text
        {get;set;}
        
        event EventHandler Click;
    }

ну  и тд..

А теперь все это добро имплементим на основе WinForms
... << RSDN@Home 1.2.0 alpha rev. 644>>
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.06 16:33
Оценка:
Здравствуйте, migel, Вы писали:

M>А теперь все это добро имплементим на основе WinForms


И в чем проблема?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Множественное наследование, mix-in-ы, traits
От: WolfHound  
Дата: 11.05.06 18:44
Оценка:
Здравствуйте, VladD2, Вы писали:

M>>А теперь все это добро имплементим на основе WinForms

VD>И в чем проблема?
В копипасте. В очень большом объеме копипаста... ибо там есть еще куча свойств которых нет в моделе WinForms.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Множественное наследование, mix-in-ы, traits
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 11.05.06 19:00
Оценка:
Здравствуйте, Kluev, Вы писали:


K>Множественное наследование отлично справляется когда есть иерархия классов и к некоторым из них нужно подключать функциональность которая не обеспечена основной иерархией. Т.е. если основная иерархия заточена под манипуляцию с данными, к одним классам добавляем визуализацию, к другим, что-то другое. Интерфейсы здесь не подходят т.к в одном флаконе требуются данные и реализация. Естественно проектировать классы надо с учетом того что они могут быть использованы во множ-наследовании.


Не только множественное наследование, но и аналог Implements в Delphi, в том числе и дельфевые хэлперы большое подспорье, а про метаклассы вообще промолчу
Есть много других хороших реализаций
и солнце б утром не вставало, когда бы не было меня
Re[6]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.06 21:44
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В копипасте. В очень большом объеме копипаста... ибо там есть еще куча свойств которых нет в моделе WinForms.


Не вижу никакой почвы для попипаста в данном случае.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Множественное наследование, mix-in-ы, traits
От: WolfHound  
Дата: 11.05.06 22:06
Оценка:
Здравствуйте, VladD2, Вы писали:

WH>>В копипасте. В очень большом объеме копипаста... ибо там есть еще куча свойств которых нет в моделе WinForms.

VD>Не вижу никакой почвы для попипаста в данном случае.
А как? Есть куча ВинФормсовских контролов. Каждый из которых должен реализовывать платформонезависимый интерфейс чтобы другие части системы могли работать независимо от того что именно ресует контролы. Скажем интерфейс IUIControl содержит порядка двух десятков элементов. А этот интерфейс должны реализовывать все видимые контролы.
Как тут обойтись без копипаста? Правильно миксины или множественное наследование реализации или макросы. Ни того ни другого ни третьего в C# нет.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 11.05.06 23:08
Оценка:
Здравствуйте, Anton V. Kolotaev, Вы писали:

AVK>Если в конечном классе не будет члена _disabled, то в определении методов enabled имя _disabled свяжется лексически? Или будет ошибка?


Ошибка. Никакого баловства с автоматическим созданием переменных нет.
Re[3]: Множественное наследование, mix-in-ы, traits
От: Freezy Россия  
Дата: 12.05.06 02:17
Оценка:
Здравствуйте, VladD2, Вы писали:

WR>

class LIKEVIEW_API Document : // Класс - Точка сборки
    public Object<LV_IDCLASS_DOCUMENT_BASE, Document>, // Объект создаваемый фабрикой
    public RefCounter,    // счётчик ссылок
    public Widget,        // базовый элемент ГУИ
    public Properties,    // контейнер свойств
    public Shape,         // фигура ГДИ
    public IdGenerator,   // генератор идентификаторов для сериализации связей
    public Port,          // узел графа схемы
    public Link,          // связь графа схемы
    public Executor       // исполнитель действий
{


VD>

// Объект создаваемый фабрикой
[ClassFabric(X)]
class Document : SchemaNode
{
    Properties Properties { get { Properties(); } }
}


VD>Вывод — очередная демонстрация того как МН приводит к ужасному дизайну "гэть в кучу".

Хотя не сторонник множественного наследования реализаций, но IMHO, атрибут в данном примере от Object<LV_IDCLASS_DOCUMENT_BASE, Document> отличается только лаконичностью. Кроме того, в C++ атрибуты отсутствуют, поэтому выход — множественное наследование. И еще, насколько я понял, класс Properties сделан классом не зря...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 12.05.06 03:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>
VD>// Объект создаваемый фабрикой
VD>[ClassFabric(X)]
VD>class Document : SchemaNode
VD>{
VD>  Properties Properties { get { Properties(); } }
VD>}
VD>


А это чего у нас такое будет?
Properties имя класса, имя свойства и имя функции?
Это дизайн такой, да?
Re[3]: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 12.05.06 07:38
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Вывод — очередная демонстрация того как МН приводит к ужасному дизайну "гэть в кучу".


Ну, VladD2, как всегда самый умный и видимо самый красивый. Давайте разбирать полеты без пристрастия. Какие мы видим грабли в приведенном примере:

class LIKEVIEW_API Document : // Класс - Точка сборки
    public Object<LV_IDCLASS_DOCUMENT_BASE, Document>, // Объект создаваемый фабрикой
    public RefCounter,    // счётчик ссылок
    public Widget,        // базовый элемент ГУИ
    public Properties,    // контейнер свойств
    public Shape,         // фигура ГДИ
    public IdGenerator,   // генератор идентификаторов для сериализации связей
    public Port,          // узел графа схемы
    public Link,          // связь графа схемы
    public Executor       // исполнитель действий


Во первых, когда в одном классе обьединяются несколько базовых возьмем для примера Properties и Shape, то могут возникнуть определенные грабли с дальнейшим наследованием, например как быть в случае UltimateProperties и AdvancedShape, НО граблей легко избежать если делать классы которые подмешиваются к основной иерархии sealed, т.е. Properties может учавствовать только как добавка при множественном наследовании, но не может быть базовым для SuperPuperProperties и т.п.

Чтобы обеспечить полиморфизм, Properties проектируется как мост к полиморфному классу PropertiesImpl от которого уже наследуются все UltimateProperties и т.п. При этом в самом Properties может быть нехилый кусок реализации и как минимум указатель, на PropertiesImpl. (к томуже Properties может так же содержать и callback интерфейс). Без множественного наследования прийдется юзать интерфейс IProperties и все остальное добавлять вручную. Т.е. в каждом классе мы будем вынуждены реализовать кучу бесполезных делегирующих функций IProperties -> PropertiesImpl, более того переменную PropertiesImpl тоже прийдется заводить ручками в каждом классе. Теперь спрашивается нафига мне этот геморой если все крассиво и безграбельно реализуется при помощи множественного наследования.

Но чаще всего получается так что никакой полиморфизм для Properties и не требуется. К примеру я ужеприводил свой кусок кода, где sealed класс для множ.насл SCX_Member (SceneMember) — является списком для полиморфных обьектов типа SceneNode, SceneMesh и т.п. и так же предоставляет callback интерфейс для обработки в верхнем обьекте событий от сцены.
Re[7]: Множественное наследование, mix-in-ы, traits
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.05.06 09:10
Оценка:
Здравствуйте, dshe, Вы писали:

CS>>Данная DisabledImpl() в том виде как объявлена может быть применена

CS>>к чему либо имеющему _disabled переменную в области применения.

CS>>Иначе — ошибка компиляции.


D>Так вот применишь ты, например, mixin DisabledImpl к чему-то, что не имеет переменной _disabled и будешь гадать, отчего же компиляция свалилась. DisabledImpl ведь к своему окружению особые требования предъявляет, только вот требования эти не локализованы, а размазаны по коду. Моменты и места, где обнаруживаются ошибки компиляции не равнозначны: я бы предпочел увидеть ошибку компиляции в месте, где DisabledImpl к чему-то применяется с сообщением, что mixin нельзя к этому применить, чем сообщение о том, что некая переменная _disabled (непонятно зачем нужная) не была найдена в DisabledImpl.


Так может эта... Может глянуть что именно компилятор D в таком случае говорит? Может он говорит, что DisabledImpl не может быть подмешен к классу из-за того, что в классе нет _disabled, который нужен DisabledImpl?

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



Пользуясь случаем хочу задать вопрос c-smile о D (прошу прощения за оффтопик, по почте с c-smile у меня не получилось связаться ). Андрей, вообще видны какие нибудь перспективы появления стабильной версии языка? А то смотришь его ChangeLog -- все время что-то меняется. Да и в списке того, что хотелось иметь, еще есть пункты. Как то стремно связываться с языком и писать код с сознанием того, что после очередного изменения в языке часть кода придется переписывать.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.05.06 20:51
Оценка:
Здравствуйте, Freezy, Вы писали:


VD>>Вывод — очередная демонстрация того как МН приводит к ужасному дизайну "гэть в кучу".

F>Хотя не сторонник множественного наследования реализаций, но IMHO, атрибут в данном примере от Object<LV_IDCLASS_DOCUMENT_BASE, Document> отличается только лаконичностью. Кроме того, в C++ атрибуты отсутствуют, поэтому выход — множественное наследование. И еще, насколько я понял, класс Properties сделан классом не зря...

Пусть так. Фабрику можно и по другому объявить. Я же говорю о другом. Возможность свалить все в кучу немедленно приводит к сваливанию всего в кучу.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.05.06 20:51
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>А это чего у нас такое будет?

CS>Properties имя класса, имя свойства и имя функции?
CS>Это дизайн такой, да?

Создание экземпляра класса. Все больше привыкаю к синтаксису Немерли.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 12.05.06 22:51
Оценка:
Здравствуйте, dshe, Вы писали:

D>Здравствуйте, c-smile, Вы писали:


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


VD>>>Здравствуйте, c-smile, Вы писали:


CS>>>>Норально решается. mixin's резолвятся во время последней фазы

CS>>>>компиляции. Поэтому такое вот работает:

VD>>>То есть никакого контроля до использования, и в добавок прямое обращение к именам из внешних классов?


CS>>Данная DisabledImpl() в том виде как объявлена может быть применена

CS>>к чему либо имеющему _disabled переменную в области применения.

CS>>Иначе — ошибка компиляции.


D>Так вот применишь ты, например, mixin DisabledImpl к чему-то, что не имеет переменной _disabled и будешь гадать, отчего же компиляция свалилась. DisabledImpl ведь к своему окружению особые требования предъявляет, только вот требования эти не локализованы, а размазаны по коду. Моменты и места, где обнаруживаются ошибки компиляции не равнозначны: я бы предпочел увидеть ошибку компиляции в месте, где DisabledImpl к чему-то применяется с сообщением, что mixin нельзя к этому применить, чем сообщение о том, что некая переменная _disabled (непонятно зачем нужная) не была найдена в DisabledImpl.


Ошибка сообщаемая компилятором двойная в этом случае:

.\harmonia\ui\controls\common.d(37): undefined identifier _disabled
.\harmonia\ui\controls\common.d(38): undefined identifier _disabled
.\harmonia\ui\controls\editbox.d(115): template instance cannot resolve forward reference

template DisabledImpl()
{
  bool disabled() { return _disabled; } // line 37
  bool disabled(bool onoff) { _disabled = onoff; return disabled(); } // line 38
}


editbox.d(115) — это в классе вставки mixin DisabledImpl!();

Если нужно что-то свое сообщить то можно наверное так:

template DisabledImpl()
{
  static if ( is (_disabled == bool))
  {
    bool disabled() { return _disabled; }
    bool disabled(bool onoff) { _disabled = onoff; return disabled(); }
  }
  else
    pragma (msg, "Warning: cannot find _disabled field of type bool");

}


На самом деле templates в D это вешь.

Don Clugston даже умудрился сделать compile time regexp.
Re[9]: Множественное наследование, mix-in-ы, traits
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 13.05.06 05:15
Оценка:
Здравствуйте, c-smile, Вы писали:

E>>Пользуясь случаем хочу задать вопрос c-smile о D (прошу прощения за оффтопик, по почте с c-smile у меня не получилось связаться ).


CS>Как так?


Да где-то месяц-полтора назад отправлял тебе пару сообщений и через RSDN и на e-mail в твоем профиле, но ответа не получил
Ну да спрашивал я у тебя там то же самое, что и сейчас. Так что ответ, в конце-концов, получил


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Множественное наследование, mix-in-ы, traits
От: c-smile Канада http://terrainformatica.com
Дата: 13.05.06 06:59
Оценка:
Здравствуйте, VladD2, Вы писали:

VD> ... Возможность свалить все в кучу немедленно приводит к сваливанию всего в кучу.


Эта максима надеюсь не из личного опыта...
Re: Множественное наследование, mix-in-ы, traits
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.05.06 13:34
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.

Вместо множественного наследования имхо подходит аналог Implements в Delphi когда за реализацию некоего интерфейса отвечает свойство класса которому передаются все вызовы.
Хэлперы (миксины) практически без особых проблем позволили приспособить дельфевую объектную модель к нетовской.
Так, что очевидно, что подобные вещи необходимы для упрощения реализации и подгонке под определенный стандарт и упрощение использования, классрв.
и солнце б утром не вставало, когда бы не было меня
Re[11]: Множественное наследование, mix-in-ы, traits
От: Freezy Россия  
Дата: 13.05.06 18:47
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Кстати все public mail сервера России в глубоком бане на форуме http://www.terrainformatica.com/bb/index.php.

Жаль, я Вам список багов (в том числе и в графическом виде) отправил...

CS>Пожалуйста используйте другие какие-нибудь адреса для регистрации.

Ладно, попробуем.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Множественное наследование, mix-in-ы, traits
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 14.05.06 11:02
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Дело в том, что вчера мне потребовалось обосновать необходимость traits в Nemerle:

VD>http://nemerle.org/forum/viewtopic.php?t=244&amp;sid=533a4646e8a58584c5dee21a456b355e
VD>и я задумался над аргументацией. Задумался, и понял, что ее в общем то у меня пока нет. Вот и решил получить помощь. Однако пока что никто ничего умного не сказал.
VD>Вот я и думаю, не является ли МН и его заменители эдакой показной фичей которая реально на фиг не упала, но так как в языке Х она есть, то и нам надо заиметь?

Так чем же история закончилась? И закончилась ли?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Множественное наследование, mix-in-ы, traits
От: Kisloid Мухосранск  
Дата: 14.05.06 13:48
Оценка:
Здравствуйте, Шахтер, Вы писали:

Я бы сделал так, написал бы просто хелпер:
    static class ByteWriterHelper
    {
        static byte[] UInt32ToBytes(uint u)
        {
            byte[] bytes = new byte [4];

            // ...

            return bytes;
        }
    }


Хотя конечно, это нарушает принцип инкапсуляции. Но с другой стороны если посмотреть, то этот хелпер может быть нужен не только ByteWriter'у, так что с точки зрения дизайна мы ничего не нарушаем. Ну а в случае когда действительно наш хелпер никому больше не нужен, то скорее всего такое решение становится костылем. Хотя это тоже спорно, зависит с какой стороны посмотреть

ЗЫ: а вот интерфейсы я бы не стал заменять абстрактными классами.
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[2]: "Узнаю тип, и узнаю калибр!" (c) Л. Буссенар
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 14.05.06 17:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что касается разнесения в пух и прах, то разношу я явно безграмотный дизайн.


В том-то и дело, что это не так.

VD>И обилие такового наводит меня на мысль, что заменители МН тоже будут порождать безграмотный дизайн. Понятно, что это зависит от поыта и знаний конкреных людей, но факт от этого фактом быть не перестает.


+1, и в самом деле, МН можно употребить откровенно криво. Но то же самое можно сказать и об ООП в общем — оно тоже порождает безграмотный ОО-дизайн. Так что, это не означает, что такой механизм в языке не нужен вообще. Примеров полезности МН продемонстрировано уже достаточно.

Засада в том, что как ни поверни, а с одной стороны, нет возможности однозначно доказать необходимость МН (Nemerle содержит, в общем, довольно мощный механизм макросов), а с другой — нет причин и отказываться от оного, если самый могучий контраргумент — потенциальное порождение "плохого" дизайна. Осциллограф тоже может ударить током, но это же не означает, что нужно от них отказываться?!

Посему, принятие решения о введении МН в Nemerle будет лежать в плоскости личных мотивов разработчиков языка. "Аргументация" сторонников МН здесь нужна только для создания видимости обоснованного решения. Её всегда можно будет вывернуть и так и эдак.

Хотя мне кажется, что как минимум один более или менее весомый аргумент можно выцарапать. А именно: как уже показали раньше, МН помогает решить некоторые проблемы использования внешних API. Так вот, кто может поручиться за то, что будущие Nemerle-API будут свободны от тех же проблем, для решения которых оказалось полезным МН?
<< Под музыку: Pink Floyd — Learning to Fly >>
<< При поддержке Янусом: 1.2.0 alpha rev. 643 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[3]: Множественное наследование, mix-in-ы, traits
От: Шахтер Интернет  
Дата: 14.05.06 20:19
Оценка:
Здравствуйте, Kisloid, Вы писали:

K>Здравствуйте, Шахтер, Вы писали:


K>Я бы сделал так, написал бы просто хелпер:

K>
K>    static class ByteWriterHelper
K>    {
K>        static byte[] UInt32ToBytes(uint u)
K>        {
K>            byte[] bytes = new byte [4];

K>            // ...

K>            return bytes;
K>        }
K>    }
K>


И дальше?

K>Хотя конечно, это нарушает принцип инкапсуляции. Но с другой стороны если посмотреть, то этот хелпер может быть нужен не только ByteWriter'у, так что с точки зрения дизайна мы ничего не нарушаем.


Мне нужен не хелпер сам по себе. Его действительн не обязательно определять внутри класса.

Мне нужен метод put(uint).

K>Ну а в случае когда действительно наш хелпер никому больше не нужен, то скорее всего такое решение становится костылем. Хотя это тоже спорно, зависит с какой стороны посмотреть


K>ЗЫ: а вот интерфейсы я бы не стал заменять абстрактными классами.


Альтернатива -- copy-past.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Множественное наследование, mix-in-ы, traits
От: Kluev  
Дата: 15.05.06 08:03
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>О как. Мы противопоставляем модль и документ. А что же тогда такое документ как не модель?


K>> который юзается для отрисовки и UI манипуляций. т.е. не классичесский doc — view, а doc — proxy_doc — view. Где doc — модель, proxy_doc — сцена3д, view — окно_сцены.


VD>Нда. Эту уже на концептуальном уровне выглядит страшно. Раньше все было просо "модель-представление-контроллер". Как разновидность интеграция контроллера в представление. Прокси использовался для создания переходника интерфейса. А тут прям новые концепции. Вот только один вопрос. А оно надо?


Тем не менее все САD-ы именно так и устроены. Все используют промежуточное представление (proxy-doc) для view.
В документе модели 3-д обьекты представлены в аналитическом виде, т.к. манипуляции и вычисление удобно делать с аналитикой и сплайнами, а графическая подсистема не понимает ничего кроме треугольников. Я еще не видел ни одной программы которая бы триангулировала бы поверхности на лету во время рендера. Такой дизайн с прокси документом очевиден и правилен, а вот обычный документ вид здесь ни на что не годится. А если графическая подсистема (view) работает только с промежуточным представлением, то об основной модели ничего знать она и не должна. И это правильно. Такой подход позволяет, например радикально изменить структуру модели не трогая view и proxy-doc. Пример — SolidWorks. В новых версиях из него оперативно выкинули покупное ядро parasolid от unigraphics и заюзали собственное. Но если вернутся к нашим баранам т.е. м-н, и постомтреть на этот дизайн doc-proxy-doc, то видно, что обьект в такой систему будет являтся обьектом модели (doc), и может являтся участником сцены (proxy-doc). Т.е. классическое отношение is-a которое подразумевает наследование. Иными словами м-н здесь уместно даже с академической точки зрения.

K>> Преимущества такого подхода очевидны.

VD>Кому, простите?
Очевиден понятливым, кто не врубается я не виноват.

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


VD>Ясно. А может вы просто про контроллер забыли?

Контроллер здесь не существенен и он совмещается с классами MainFrame и Docking Windows, вернее MainFrame и докируемые окна это и есть контроллеры, заводить отдельный класс нет смысла.

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


VD>Ну, вот мы и пришли к странному дизайну.

Расскажи это людям которые пишут Unigraphics, SolidWorks, PRO/E и другие системы, а то мужики не знают, делают странный дизайн, извращаются.

VD>В общем, чем дальше читаю эту тему, тем больше понимаю, что проблем от МН больше чем приемуществ. А ведь еще не давно я так не думал.


Не нарвится не используй никто не настаивает. Я например в ходе практики выяснил все плюсы, минусы и подводные грабли в М-Н. Поэтому юзаю там где считаю нужным. Чужие теоретические рассуждения о М-Н, мне совершенно фиолетовы.
Re[5]: Множественное наследование, mix-in-ы, traits
От: WoldemaR Россия  
Дата: 16.05.06 09:43
Оценка:
Здравствуйте, A.Lokotkov, Вы писали:

AL>Не могли бы Вы привести ссылок на тему отказа индустрии от ПРО?


Вот ссылок привести немогу. Но если Вы посмотрите последние версии векторных графических редакторов: типа Corel, Flash, Xara, и т.п. то заметите что существует возможность трансформации объекта из одного "типа" в другой "тип", т.е. все объекты равнофункциональны.

А чему нас учили?
class DrawObject{};

class Line : DrawObject{};
class Circle : DrawObject{};
class Square : DrawObject{};


В современных редакторах происходит такая вещь:
Circle obj;
obj = cast<Square>(obj);


Надеюсь что понятно объяснил.
Re[6]: Множественное наследование, mix-in-ы, traits
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.05.06 20:31
Оценка:
WR>В современных редакторах происходит такая вещь:
WR>
WR>Circle obj;
WR>obj = cast<Square>(obj);
WR>


Но ведь может быть и такой код:
Figure obj = new Circle();
obj = obj.ConvertTo<Square>();
Re[8]: Множественное наследование, mix-in-ы, traits
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.05.06 20:09
Оценка:
WR>Несмотря на то, что мазохизм иногда встречается в самых неожиданных формах, это не является поводом принимать извращения за правило.

А четко обосновать почему это так, сможете? или только можете общие фразы выдавать?
Re[6]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.05.06 20:53
Оценка:
Здравствуйте, eao197, Вы писали:

E>Так чем же история закончилась? И закончилась ли?


Какая? Я просто собираю солидную аргументацию чтобы использовать ее при объяснении зачем это нужно в Немерле.

Просто я думл только собрать аргументы, а получилось так, что задумался по глубже...
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Множественное наследование, mix-in-ы, traits
От: WoldemaR Россия  
Дата: 18.05.06 09:44
Оценка:
Здравствуйте, DarkGray, Вы писали:


WR>>Несмотря на то, что мазохизм иногда встречается в самых неожиданных формах, это не является поводом принимать извращения за правило.


DG>А четко обосновать почему это так, сможете? или только можете общие фразы выдавать?


Понимаете в чём дело.
Если вам нравится выполнение рутинной работы, а у вашего начальства достаточно денег для использования трудоёмких текнологий, то кто я такой чтобы говорить Вам, что это плохо?
Re[9]: Множественное наследование, mix-in-ы, traits
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.05.06 20:52
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>А четко обосновать почему это так, сможете? или только можете общие фразы выдавать?


Ты не понял. Он же сказал "индустрия уже отказалась". Просто она сказала это толко ему одному. А мы просто еще не в крусе.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Множественное наследование, mix-in-ы, traits
От: WoldemaR Россия  
Дата: 19.05.06 11:05
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ты не понял. Он же сказал "индустрия уже отказалась". Просто она сказала это толко ему одному. А мы просто еще не в крусе.


VladD2, да ты не комплексуй. у каждого человека есть слабые и сильные стороны.
Re: немного не по теме
От: mrozov  
Дата: 19.05.06 18:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Хотелось бы услышать кто что думает по поводу необходимости подобных вещей в языках программирования.


VD>Особо привествуются примеры в которых данные фичи дают резкое упрощение решаемой задачи.


Возможно, баян и злостный оффтопик, но все-таки.


    interface IMixin
    {}

    class SomeClass : IMixin
    {
    }

    static class Mixin
    {
        public static void DoSmth( this IMixin o )
        {
        }
    }
    
    class Pro
    {
        
        public static void Work()
        {
            SomeClass o = new SomeClass();
            
            IMixin mixin = o;
            
            mixin.DoSmth();
        }
    }

Конечно, так красиво все только для stateless mixin-ов, но я все равно шизею от дорогой редакции... Что они творят с моим любимым языком?
Re[2]: немного не по теме
От: WolfHound  
Дата: 19.05.06 19:19
Оценка:
Здравствуйте, mrozov, Вы писали:

M>Конечно, так красиво все только для stateless mixin-ов, но я все равно шизею от дорогой редакции... Что они творят с моим любимым языком?

Это сахар, а не миксины. Этим баловством нельзя реализовавать интерфейсы. Короче толку мало.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: немного не по теме
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.05.06 21:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

M>>Конечно, так красиво все только для stateless mixin-ов, но я все равно шизею от дорогой редакции... Что они творят с моим любимым языком?

WH>Это сахар, а не миксины. Этим баловством нельзя реализовавать интерфейсы. Короче толку мало.

Толку много, но решается другая задача.

И вот еще что... Хорошо, что они творят хотя бы это с нашим любимым языком.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: немного не по теме
От: Кирилл Осенков Украина
Дата: 05.09.07 19:27
Оценка:
M>
M>    interface IMixin ...
M>    ...
M>    static class Mixin
M>    {
M>        public static void DoSmth( this IMixin o )
M>        {
M>        }
M>    } ...
M>

M>Конечно, так красиво все только для stateless mixin-ов, но я все равно шизею от дорогой редакции... Что они творят с моим любимым языком?

Да, extension methods открывают интересные возможности:
Create Mixins with Interfaces and Extension Methods

Если я правильно понял, это решает проблему Шахтёра
Автор: Шахтер
Дата: 11.05.06
— интерфейс содержит часть реализации по умолчанию. Очень похоже на то, как это сделано в Хаскелле — можно реализовать некий кусок интерфейса, а остальной кусок реализуется автоматически.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.