Re[7]: О множественном наследовании
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.09.12 09:48
Оценка:
Здравствуйте, vdimas, Вы писали:

AVK>>Не обязательно. Для примера — как думаешь, что порождает большую связность — встроенные в CLR эвенты или IObservable из 4+ фреймворка?


V>Это смотря как на эвенты подписываться. А то ведь можно и через EventDescriptor.


Ну то есть ты понимаешь, что обсервер обсерверу рознь. А между наследованием и агрегацией, пусть и с маппингом агрегируемого объекта на внешний интерфейс, разница существенно больше.
... << RSDN@Home 1.2.0 alpha 5 rev. 65 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[8]: О множественном наследовании
От: vdimas Россия  
Дата: 03.09.12 11:32
Оценка: -1
Здравствуйте, AndrewVK, Вы писали:


V>>Это смотря как на эвенты подписываться. А то ведь можно и через EventDescriptor.

AVK>Ну то есть ты понимаешь, что обсервер обсерверу рознь. А между наследованием и агрегацией, пусть и с маппингом агрегируемого объекта на внешний интерфейс, разница существенно больше.

Я вижу разницу только в случае абстрактного интерфейса агрегируемого объекта. Но это, в некотором роде опасная штука дизайна сама по себе... в том смысле, что это ведь основа многих структурных паттернов и возможные эффекты от такого дизайна могут быть неожиданными для разработчика, если применение сих паттернов было "случайным". ИМХО, любое DI должно быть элементом сознательного решения некоего сценария, а не навязанным сверху ограничением.

=================
Это я насчет того, что куча неких локальных типов с сильной связанностью для некоей локальной задачи по мне ни разу не зло. Связанность по-прежнему может регулироваться самим дизайном основных объектов и сценариев их взаимного использования в технике уже имеющегося мейнстримового ООП. Проблемы нет, ведь требуемое кол-во архитекторов по-прежнему резко меньше требуемого кол-ва програмистов "бизнес-логики". ИМХО, где у разработчика ОО-иерархии возникнут проблемы в текущей мейнстримовой технике, они так же возникнут в любой технике. Мои некоторые наблюдения из разработки на VB тому пример — половина программистов на VB даже толком не понимало, как работает низлежащий COM/OLE, но это им ничуть не мешало быть достаточно полезными для типовых бизнес-задач. А всё потому, что на VB нельзя разработать COM-интерфейс. Эти интерфейсы разрабатывались гораздо более грамотными людьми на COM-IDL и давались "сверху" как каркас. То бишь, ограничивать надо не грамотных, а безграмотных.
Re[9]: О множественном наследовании
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.09.12 12:42
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Я вижу разницу только в случае абстрактного интерфейса агрегируемого объекта.


Агрегирование и делается исключительно через публичный контракт агрегируемого объекта. Иначе это не агрегация, а профанация.

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


Смысла фразы не уловил.

V> ИМХО, любое DI должно быть элементом сознательного решения некоего сценария, а не навязанным сверху ограничением.


При чем тут DI?

V>Это я насчет того, что куча неких локальных типов с сильной связанностью для некоей локальной задачи по мне ни разу не зло.


Наследование мейнстримное нелокально в принципе. И, за исключением приватного наследования С++, фигурирует в публичном контракте наследника в обязательном порядке.
Хуже того, сам механизм наследования оправдан в случае довольно крупных кусков архитектуры, для мелких он слишком много требует синтаксических танцев. В результате на практике мы наблюдаем прежде всего попытки построения дизайна приложения, а не решение локальных задач.
... << RSDN@Home 1.2.0 alpha 5 rev. 65 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[4]: О множественном наследовании
От: LaptevVV Россия  
Дата: 03.09.12 14:53
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


LVV>>3. Хотелось прояснить для себя некоторые вопросы — вот в частности с наследованием. Кроме того, пацан в процессе реализации интерпретатора наткнулся на интересную штуку: оказалось, ссылочную семантику и семантику значений можно реализовать в рамках одного язвка. И появилась возможность одной кнопочкой переключать это дело. Более того, если сделать API, то можно и в процессе интерпретации переключать эту семантику.

WH>Чего? Это же радикально меняет поведение кода.
Естественно!!!!
Дык для того и делалось, чтобы учни могли попробовать в учебной среде и обнаружить существенную разницу...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: О множественном наследовании
От: WolfHound  
Дата: 03.09.12 15:19
Оценка:
Здравствуйте, LaptevVV, Вы писали:

WH>>Чего? Это же радикально меняет поведение кода.

LVV>Естественно!!!!
LVV>Дык для того и делалось, чтобы учни могли попробовать в учебной среде и обнаружить существенную разницу...
Честно говоря воспитательный эффект весьма сомнительный.
Не понимаю, что может понять ученик глядя на то, как отлаженная программа начала глючить.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: О множественном наследовании
От: LaptevVV Россия  
Дата: 03.09.12 15:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


WH>>>Чего? Это же радикально меняет поведение кода.

LVV>>Естественно!!!!
LVV>>Дык для того и делалось, чтобы учни могли попробовать в учебной среде и обнаружить существенную разницу...
WH>Честно говоря воспитательный эффект весьма сомнительный.
WH>Не понимаю, что может понять ученик глядя на то, как отлаженная программа начала глючить.
Ну дык а препод-то на что?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[10]: О множественном наследовании
От: vdimas Россия  
Дата: 03.09.12 15:33
Оценка:
Здравствуйте, AndrewVK, Вы писали:

V>>Я вижу разницу только в случае абстрактного интерфейса агрегируемого объекта.

AVK>Агрегирование и делается исключительно через публичный контракт агрегируемого объекта. Иначе это не агрегация, а профанация.

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


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

AVK>Смысла фразы не уловил.

Слишком много степеней свободы появляется... ИМХО, типобезопасный абстрактный интерфейс — это контракт только наполовину, только в плане сигнатур методов, где обещание насчет соблюдение семантики контракта сугубо вербальное и никак иначе.

V>> ИМХО, любое DI должно быть элементом сознательного решения некоего сценария, а не навязанным сверху ограничением.

AVK>При чем тут DI?

Если агрегируемый объект абстрактен, то это смахивает на классическое DI после IoC.

V>>Это я насчет того, что куча неких локальных типов с сильной связанностью для некоей локальной задачи по мне ни разу не зло.

AVK>Наследование мейнстримное нелокально в принципе. И, за исключением приватного наследования С++, фигурирует в публичном контракте наследника в обязательном порядке.

Да вроде не мешает, есть же классический паттерн "Мост", который обыгрывает разницу м/у внутренней иерархией и публичной.


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


ИМХО, всё-равно это от квалификации разработчика зависит. Для некоторого уровня разработчика сам факт более-менее надежного решения прикладной задачи уже неплох. Более опытный коллега может сделать затем ревью и рефакторинг. Так вот, первого разработчика обсуждаемое не спасет, а второму банально не нужно.
Re[11]: О множественном наследовании
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.09.12 15:41
Оценка:
Здравствуйте, vdimas, Вы писали:

AVK>>Агрегирование и делается исключительно через публичный контракт агрегируемого объекта. Иначе это не агрегация, а профанация.


V>Если этот контракт виртуальный/абстрактный, то контроль за происходящим в конкретном месте уже не тот.


Ничего не понял


AVK>>Смысла фразы не уловил.


V>Слишком много степеней свободы появляется... ИМХО, типобезопасный абстрактный интерфейс — это контракт только наполовину, только в плане сигнатур методов, где обещание насчет соблюдение семантики контракта сугубо вербальное и никак иначе.


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

V>>> ИМХО, любое DI должно быть элементом сознательного решения некоего сценария, а не навязанным сверху ограничением.

AVK>>При чем тут DI?

V>Если агрегируемый объект абстрактен, то это смахивает на классическое DI после IoC.


Классический IoC никакой агрегации не предполагает и опысывает внешние связи разнородных сущностей.

V>ИМХО, всё-равно это от квалификации разработчика зависит.


Чем меньше возможности сделать бяку, тем лучше, вне зависимости от квалификации разработчика.
... << RSDN@Home 1.2.0 alpha 5 rev. 65 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[7]: О множественном наследовании
От: WolfHound  
Дата: 03.09.12 16:03
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Ну дык а препод-то на что?

Ну, объяснишь. Вернее попробуешь. Только никто ничего не поймет.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: О множественном наследовании
От: vdimas Россия  
Дата: 03.09.12 18:44
Оценка:
Здравствуйте, AndrewVK, Вы писали:

V>>Если этот контракт виртуальный/абстрактный, то контроль за происходящим в конкретном месте уже не тот.

AVK>Ничего не понял

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


V>>Если агрегируемый объект абстрактен, то это смахивает на классическое DI после IoC.

AVK>Классический IoC никакой агрегации не предполагает и опысывает внешние связи разнородных сущностей.

Агрегация по ссылке недалеко ушла от обычной связи разнородных сущеностей. А агрегация по значению имеет ровно те же эффекты, что обычное наследование (о чем и сказал тут: http://www.rsdn.ru/forum/philosophy/4877921.aspx
Автор: vdimas
Дата: 02.09.12
). Очевидно, что возражения на тот пост уместны только если иметь ввиду агрегацию по ссылке и твой пример насчет IObservable тому подтверждение.


V>>ИМХО, всё-равно это от квалификации разработчика зависит.

AVK>Чем меньше возможности сделать бяку, тем лучше, вне зависимости от квалификации разработчика.

Дык, не спорю, главное, чтобы не в ущерб. ИМХО, если без особого фанатизма, то локальные иерархии объектов очень даже удобны. Просты, лаконичны, беспроблемны. Насчет "спрятать от остального кода" — пользуемся паттерном "Мост" и всех делов. Обычно за небольшой публичной иерархией моста может прятаться приличная непубличная, что решает обсуждаемые здесь вопросы. К тому же, полный контроль дотнета над переопределением методов интерейсов я бы сказал провоцирует на такой стиль.
Re[13]: О множественном наследовании
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.09.12 19:11
Оценка: 33 (1)
Здравствуйте, vdimas, Вы писали:

V>>>Если этот контракт виртуальный/абстрактный, то контроль за происходящим в конкретном месте уже не тот.

AVK>>Ничего не понял

V>А что тут непонятного?


Вообще ничего не понятно.

V> Например, подменить базовый класс в обычном наследовании никак, а в агрегировании можно подменить чем угодно.


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

AVK>>Классический IoC никакой агрегации не предполагает и опысывает внешние связи разнородных сущностей.


V>Агрегация по ссылке недалеко ушла от обычной связи разнородных сущеностей


Зачем это натягивание презерватива на глобус? Практический то вывод какой из твоих замысловатых построений?

V>. А агрегация по значению имеет ровно те же эффекты, что обычное наследование


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

AVK>>Чем меньше возможности сделать бяку, тем лучше, вне зависимости от квалификации разработчика.


V>Дык, не спорю, главное, чтобы не в ущерб.


Ну и какая такая уникальная ценность у наследования классов, которую невозможно обеспечить более безопасными средствами?

V> ИМХО, если без особого фанатизма, то локальные иерархии объектов очень даже удобны. Просты, лаконичны, беспроблемны.


1) Вовсе не просты. Наследованием ты на ровном месте порождаешь весьма высокую связность, как по внутренностям, так, что еще печальнее, по публичному контракту. И устранить это вообще никак невозможно.
2) Про лаконичность вообще смешно. Чтобы подмешать функциональность целый класс плодить вовсе необязательно.
3) Беспроблемность тоже сродни беспроблемности ручного управления памяти. Она достигается только при соблюдении 100500 условий, которые компилятором не контролируются и даже не поощряются. И все это без каких либо бенефитов от такого слонопотамистого и негибкого механизма с кучей побочки.

V> Насчет "спрятать от остального кода" — пользуемся паттерном "Мост" и всех делов


То есть куча синтаксического мусора продолжает пухнуть. Особенно эротично получается, когда мост тоже нужно сделать довольно богатым по контракту (передать дерево с разнотипными узлами, к примеру). А когда нам надо оторвать виртуальный метод о иерархии? Будем визитор ваять и раздувать ворох пустого кода еще больше? При этом, при грамотном подходе, всей этой фигни можно избежать, всего то оторвав наследование контрактов от наследования реализаций.
... << RSDN@Home 1.2.0 alpha 5 rev. 65 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[14]: О множественном наследовании
От: vdimas Россия  
Дата: 03.09.12 23:02
Оценка: -2 :)
Здравствуйте, AndrewVK, Вы писали:

V>>Агрегация по ссылке недалеко ушла от обычной связи разнородных сущеностей

AVK>Зачем это натягивание презерватива на глобус?

ИМХО, игнорировать происходящее при этом и есть натягивание непонятно чего непонятно на что. В случае связи по ссылке агрегирование превращается в условность.


V>>. А агрегация по значению имеет ровно те же эффекты, что обычное наследование

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

В обощенной форме можно прямо сейчас посмотреть в С++, где допустимо отнаследоваться от параметра-типа шаблонного класса. Всё тоже самое.


AVK>Ну и какая такая уникальная ценность у наследования классов, которую невозможно обеспечить более безопасными средствами?


Ценность в лаконичности. Ценность в том, что работает ОО-парадигма в дизайне: ищем общее и обыгрываем частное. Любое автоматическое делегирование лишь усилит все твои опасности, т.к. к имеющемуся автоматическому делегированию конкретной базе добавится точно такое же делегирование, только уже к произвольной. Угу, включая null. Это мы еще не обсуждали +1 косвенность на каждой операции делегирования... а сколько их будет в реальных проектах? От 5 до 10-ти? Это столько раз надо будет разыменовать ссылки, чтобы прочесть поле тривиального типа?

И я уже приводил пример VB/VBA. Ты фактически предлагаешь ограничится техникой наподобие VB/VBA, хотя всё мировое сообщество считало VB.Net шагом вперед.

V>> ИМХО, если без особого фанатизма, то локальные иерархии объектов очень даже удобны. Просты, лаконичны, беспроблемны.

AVK>1) Вовсе не просты. Наследованием ты на ровном месте порождаешь весьма высокую связность, как по внутренностям, так, что еще печальнее, по публичному контракту. И устранить это вообще никак невозможно.

Это смотря как каркас дизайна устроен. Если интерфейсы каркаса даны "сверху", то подробности конкретных типов-реализаторов никого не интересуют и вообще не видны.

AVK>2) Про лаконичность вообще смешно. Чтобы подмешать функциональность целый класс плодить вовсе необязательно.


В тру-ООП обязательно. Кастомные конструкторы Джавы в пример. Функциональщина дотнета — это тоже сахар над ООП унутре.

AVK>3) Беспроблемность тоже сродни беспроблемности ручного управления памяти. Она достигается только при соблюдении 100500 условий, которые компилятором не контролируются и даже не поощряются. И все это без каких либо бенефитов от такого слонопотамистого и негибкого механизма с кучей побочки.


Ты упустил весь контекст относительно локальности иерархий. То бишь, условий не 100500, а ровно одно — видимость подробностей. Просто "Мост" я уже 3-й раз напоминаю.

Вопрос: а интерфейсы ты тоже наследовать не будешь? А если будешь — в чем принципиальная разница?

V>> Насчет "спрятать от остального кода" — пользуемся паттерном "Мост" и всех делов


AVK>То есть куча синтаксического мусора продолжает пухнуть.


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

AVK>Особенно эротично получается, когда мост тоже нужно сделать довольно богатым по контракту (передать дерево с разнотипными узлами, к примеру). А когда нам надо оторвать виртуальный метод о иерархии? Будем визитор ваять и раздувать ворох пустого кода еще больше? При этом, при грамотном подходе, всей этой фигни можно избежать, всего то оторвав наследование контрактов от наследования реализаций.


Кто тебе мешает это сделать прямо сейчас и посмотреть, во что это выльется? Плавали, знаем. Это работает только на самом высокоуровневом слое "клея", где относительно немного сущностей, м/у которыми заведомо сильная связь. А если же стремиться к твоей цели — низой связанности... то т как-то упустил из виду, что весь внутренний дизайн в случае явного агрегирования — это и будет сплошной "Мост", как он было в проектах на VB. Что простейший паттерн "шаблонный метод" у тебя должен будет трансформироваться в намного более сложный в обслуживании "стратегию", что визиторы у тебя будут сами по себе мостом и/или одновременно адаптерами к 2-м (минимум к 2-м) отношениям пар ничего не знающих друг о друге интерфейсов. Вот распиши ради смеха визитор в условиях агрегации независимых типов как со стороны посетителя, так и со стороны посещаемого... — это же застрелиться. Обычное делегирование, которое могло бы быть выполнено с помощью синтаксического сахара компилятора — уппсс, уже не работает, как только нам нужно от агрегированного объекта получать хоть какой-то callback, как в двойной диспетчеризации... ведь для обеспечения работы калбэка надо будет выполнить уже "обратное" агрегирование. И так на каждый малейших чих. И что самое опасное, при обратном агрегировании мы можем потерять самое ценное в визиторе — конкретный тип узла. Таки ооочень рекомендую набросать визитор в условиях агрегирования, когда агрегируемый объект ничего не знает о посетителе (как ты хотел).

Как по мне, то овчинка выделки не стоит.
Re[15]: Визитор
От: Qbit86 Кипр
Дата: 04.09.12 00:33
Оценка:
Здравствуйте, vdimas, Вы писали:

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


Двойная диспетчеризация делается двумерной табличкой функций (хэш-мэп, отображающий пару типов на операцию над ними).
Глаза у меня добрые, но рубашка — смирительная!
Re[6]: О множественном наследовании
От: B0FEE664  
Дата: 04.09.12 10:30
Оценка:
Здравствуйте, Privalov, Вы писали:

Ф>>Наследование реализации — вещь полезная, т.к. позволяет экономить усилия.

P>Наследование реализации — зло. В одном из проектов было примерно 8 уровней наследования, причем довольно часто оно применялось только за тем, что в наследуемом классе был подходящий метод. И делали такое не студенты, а вполне взрослые дядьки. В таком коде, если где-то обнаруживается бага, починить ее стоит совершенно адских усилий.

Почему?
И каждый день — без права на ошибку...
Re[7]: О множественном наследовании
От: Privalov  
Дата: 04.09.12 11:21
Оценка:
Здравствуйте, B0FEE664, Вы писали:

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


BFE>Почему?


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

[offtopic]
Главное, все знают, "так нельзя". Но все равно делают. Говорят "потом напишем, как надо", хотя все знают, что никто и никогда не напишет.
Однажды один начальник произнес: "Главное — укладываться в сроки. Качество кода — в печку".
[/offtopic]
Re[16]: Визитор
От: vdimas Россия  
Дата: 04.09.12 11:48
Оценка: -1
Здравствуйте, Qbit86, Вы писали:

Q>Двойная диспетчеризация делается двумерной табличкой функций (хэш-мэп, отображающий пару типов на операцию над ними).


В случае агрегирования возникают ньюансы и комбинаторные соцетания сценариев.
Ты, похоже, упустил, что в случае обычного наследования мы имеем отношение потомок:база как 1:1, а в случае агрегирования не по значению, а по ссылке — 1:oo.

Возникает вопрос: и что тогда считать типом "узла"? Правильно, это уже будет зависеть от сценария. Самый любопытный сценарий тот, когда тип узла определяется типом агрегирумого объекта (развернув иерархию ты увидишь классический "мост" в этом сценарии), но агрегированный объект ничего у нас не знает о посетителе, ведь тот находится на другой стороне "моста". Именно этот сценарий ради смеха я предложил расписать, как он будет выглядеть на визиторе. Расписать этот сценарий несложно, но он покажет всё убожество техники агрегирования, если применять эту технику "просто лишь бы было". Агрегирование по ссылке и так слишком часто используется в структурных паттернах, по-сути являясь их фундаментом... Но эти паттерны обычно решают какую-то полезную задачу, то бишь оправданы. Использовать же агрегацию без того, чтобы эта техника решала некий полезный момент дизайна будет источником дополнительных проблем, как и любой другой оверкилл... на мой взгляд это будет несерьезный подход к проектированию.
Re[8]: О множественном наследовании
От: B0FEE664  
Дата: 05.09.12 12:46
Оценка:
Здравствуйте, Privalov, Вы писали:

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

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

Звучит странно. Это звучит так, как будто реализация виртуальной функции "знает" о классах-наследниках. Скорее всего это значит, что код функции реализован не на своём уровне иерархии.
И каждый день — без права на ошибку...
Re[2]: О множественном наследовании
От: maxkar  
Дата: 05.09.12 17:43
Оценка: 12 (2)
Здравствуйте, AndrewVK, Вы писали:

AVK>Мое предложение — множественное наследование интерфейсов и отсутствие наследования реализаций. Т.е. классы вообще не наследуются. А для реюза кода придумать способ упрощения агрегации.


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

Сама идея вполне естественно возникает в тех языках, где функция — объект первого класса. Периодически во всякие трансформаторы (вроде map и т.п.) хочется скормить конструктор объекта. А нельзя . Чисто теоретически, можно сделать синтаксическую конструкцию вида "map (new SomeClass) ... и это будет работать. Но останется еще одна проблема — перегрузка конструктора по имени и "неравноправие" конструкторов. Пример:
public class Rectangle {
  public Rectangle(int x, int y, int width, int height) {...}
  public static Rectangle createByPoints(int x1, int y1, int x2, int y2) { return new Rectangle(x1, y1, x2-x1, y2-y1); }
}

Проверки и т.п. можно добавить. createByPoints можно с двумя точками сделать, но я не хочу (для данного примера). Логичное решение здесь — сделать еще статический метод createByPointAndSize, а конструктор сделать приватным. Но все равно остается лишний код конструктора и обертка к нему. Немного, но писать все же лень.

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

Как примерно это может выглядеть:
public class Rectangle {
  public constructor byPointAndSize(int x, int y, int width, int height) { this.x = x; this.y = y; ... }
  public static Rectangle byPoints(int x1, int y1, int x2, int y2) { return Rectange.byPointsAndSize(x1, y1, x2-x1, y2-y1); }
  public constructor square(int x, int y, int width) {
    initialize byPointAndSize(x, y, width, width);
  }
}

Конструктор (constructor) — это с точки зрения всего остального кода static <T> метод. T — класс, внутри которого объявлен конструктор. Все остальные модификаторы (доступ и т.п.) — как обычно. Внутри метода ведет себя почти как instance method (т.е. имеет this). Почти, потому что имеет специальную форму — вызов других инициализаторов ininialize(аналог существующих вызовов других конструкторов из конструктора). Соответственно, при генерации и выполнении сначала выделяется память и затем вызывается инициализатор (с уже существующим this). initialize — вызов другого инициализатора (без выделения памяти!). На вызов initialize можно навесить те же ограничения, которые навешиваются на вызов других конструкторов из конструктора (например, может быть только первым statement в конструкторе).

Итого. Вроде бы реализуемо. И получаются "first class constructors", которые являются обычными статическими методами. По синтаксису в простейших случаях можно сделать очень похожим на "стандартные" конструкторы, вместо new Point(3, 5) будет Point.new(3,5). Так что простые сценарии подобный подход не усложняет.
Re[3]: О множественном наследовании
От: LaptevVV Россия  
Дата: 06.09.12 04:43
Оценка: 6 (1)
Здравствуйте, maxkar, Вы писали:

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


AVK>>Мое предложение — множественное наследование интерфейсов и отсутствие наследования реализаций. Т.е. классы вообще не наследуются. А для реюза кода придумать способ упрощения агрегации.


M>Я тоже за эту идею. И хочу еще одну штуку, тесно связанную с отсутствием наследования реализаций. Я хочу избавиться от new ... и "конструкторов" как таковых. Методы "создания" объектов — это "обычные" с точки зрения всего остального кода статические методы.

Ты будешь смеяться, но конструкторов у нас нет с самого начала...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: О множественном наследовании
От: _NN_ www.nemerleweb.com
Дата: 06.09.12 09:49
Оценка: +1
Здравствуйте, maxkar, Вы писали:

M>Сама идея вполне естественно возникает в тех языках, где функция — объект первого класса. Периодически во всякие трансформаторы (вроде map и т.п.) хочется скормить конструктор объекта. А нельзя .

Добро пожаловать на светлую сторону Nemerle

using System.Console;
using Nemerle.Collections;

class A
{
 public this(i : int) { WriteLine(i); }
}

def aObjects = [1,2,3,4].Map(A);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.