Namespaces vs. Tags (Facets)
От: 0x7be СССР  
Дата: 12.03.11 20:25
Оценка: 19 (3) +3
Сейчас для логической организации во "мэйнстримовых" языках применяется иерархическая организация — пространства имен, пакеты и т.п. Однако жизнь штука сложная и не всегда хорошо вписывается в иерархическую схему. У меня часто возникали ситуации, когда более естественным способом организовать типы и функции в программе была бы фасеточная классификация, где гранями являются функциональные аспекты системы. Но фасеточная классификация неоднозначно отображается в иерархическую, что порождает некоторые проблемы, особенно если над проектом работает несколько людей.

Собственно, вопрос: как Вы думаете, имеет ли право на полную и насыщенную пользой жизнь идея организации программ через систему граней/тэгов?
В принципе, это возможно и при поддержке со стороны языка, так и чисто инструментальными средствами. Например, плагин в IDE, который "заряжается" тэгами и строит на основании их иерархию определенным образом, заодно следя, что бы программист ручками не нарушил правильного порядка. Например, это было бы вполне естественной епархией решарпера.
Re[2]: DAG
От: Qbit86 Кипр
Дата: 15.03.11 16:19
Оценка: 15 (2) +1
Здравствуйте, barn_czn, Вы писали:

_>А самая удобная модель структуры — дерево.


А самая естественная — даг (directed acyclic graph), т.е. граф без циклов но, возможно, с контурами (т.е. как дерево, но у каждого узла может быть несколько родителей). Все эти ваши теги, грани или фасеты какие-то — суть завуалированные даги.

_>А самая удобная модель структуры — дерево.


Рассмотрим другой пример. Как организовать структуру файлов проекта?
Первый вариант:
/Bin
  /Project1
  /Project2
/Doc
  /Project1
  /Project2
Src/
  /Project1
  /Project2

Второй вариант:
/Project1
  /Bin
  /Doc
  /Src
/Project2
  /Bin
  /Doc
  /Src


И то, и другое — дерево, но какое предпочесть? Второй вариант — это транспонированный первый, вывернутый наизнанку. Такая ситуация возникает (как и у топик-стартера), когда есть независимые критерии (аспекты), по которым стоит разделять сущности (антивир/антиспам, скачивалка/интероп). Эти признаки образуют n-мерный параллелепипед. Чтобы зафиксировать иерархическую структуру, надо умостить параллелепипед в плоскость, т.е. упорядочить критерии, произвольно выбрать порядок в котором расслаиваем параллелепипед. Таким образом, попытка умостить набор сущностей в прокрустово ложе дерева, на самом деле, приводит к потере информации об исходной структуре.
Глаза у меня добрые, но рубашка — смирительная!
Re[5]: Примеры
От: Sinix  
Дата: 13.03.11 09:25
Оценка: 2 (2) +1
Здравствуйте, 0x7be, Вы писали:
0>Нет, способ классификации мы придумали
0>Только он получился фасеточный, а не иерархический
0>Какое "множество равноправных иехрархий", откуда?

Ну смотрите, у нас есть 2 крайних варианта:
1) (очевидно, не ваш случай) фасеты не пересекаются — что мешает их переобозвать в namespace?
2) одни и те же классы используются в нескольких фасетах — что мешает вынести эти классы в отдельные namespace?

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

Основное предназначение namespace-ов — самодокументирование, отражение структуры проекта и пояснение назначения его составляющих. Если перейти к меткам, то у нас всё вышеперечисленное отпадает и появляется куча вопросов аля
— "[Antivirus].Downloader" и "[AdwareBlocker].Downloader" — это один и тот же класс, или несколько?
— Если один — почему он нарушает SRP и делает 2 работы одновременно?
— Если он не нарушает, и это просто универсальный класс — каким боком он относится к антивирусу или адблоку?




0>Да, есть модуль "скачивалка", а есть модули, адаптирующие его к антивирю и антисмаму, ибо есть у них в плане качения баз своя специфика. То есть модули, которые связаны И со скачивалкой И с антивирусом/антиспамом.
0>Куда их помещать в единой иерархической структуре?
Последний идентификатор — имя класса.

Для _больших_ проектов:
-YourCompany.Components.Net.Downloader,
-YourCompany.YourProduct.SelfUpdate.UpdaterBase,
-YourCompany.YourProduct.Feature1.SelfUpdate.Feature1Updater,
-YourCompany.YourProduct.Feature2.SelfUpdate.Feature2Updater.

Для мелких:
-YourCompany.Net.Downloader,
-YourCompany.Antivirus.AntivirusUpdater,
-YourCompany.AdwareBlocker.AdwareBlockerUpdater.

Смысл такого разделения, в том, что _используемый_ компонент не должен ничего знать об остальном коде. Иначе у вас возникает сильная связь между всеми частями проекта: начинаете править downloader под сценарий для антивируса, ломаете адблокер.

0>А интероп — это вообще отдельный аспект подсистемы, в которой задействован нативный компонент. То есть свой интероп есть и у антивиря, и у антиспама, и у скачивалки и ещё есть.

Ну если это просто вспомогательный код, и он никак не переиспользуется — пусть живёт в YourCompany.Antivirus.Interop. При чём здесь фасеты?

Попробую ещё раз сформулировать свою точку зрения, чтобы не было разночтений:
Метки полезны только для поиска. Когда нет структуры, она не отражает действительность, или нет никакого желания в ней разбираться. Предлагать метки как основное решение — мягко говоря, ересь
Re: Примеры
От: Qbit86 Кипр
Дата: 12.03.11 20:36
Оценка: +3
Здравствуйте, 0x7be, Вы писали:

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


Реквестирую содержательные примеры, наводящие соображения и прочие промежуточные звенья рассуждений, что привели топик-стартера к вопросу в исходном сабже.
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: Примеры
От: Sinix  
Дата: 13.03.11 07:53
Оценка: +2
Здравствуйте, 0x7be, Вы писали:

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

А почему вы думаете, что с тегами будет проще? Проблема — не в способе описания, а в том, что вы пытаетесь применить средство самодокументирования к области, для которой вы ещё не придумали способ классификации.

Если вы перейдёте к меткам, то фактически будете поощрять дальнейшую энтропию. Всё, что вы получите — множество равноправных иерархий вместо одной, но частично кривой. Посмотрите на самые удачные примеры тегирования — wiki и stackowerflow. Как, удобно?

Summary: если бардак не автоматизируется, неймспейсы винить как-то глупо

Если вернуться к примеру с антивирусом — почему нельзя было пойти самым простым путём — завести
YourCompany.Antivirus, YourCompany.Helpers.Downloader, YourCompany.Helpers.Interop etc?

Зачем вводить двустороннюю связность в именование и в архитектуру проекта? У вас что, скачивалка зависит каким-либо образом от антивируса? А интероп использует API скачивалки? Зачем их смешивать?
Re[8]: Примеры
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.03.11 20:03
Оценка: 9 (1)
Здравствуйте, Sinix, Вы писали:


0>>Это в зависимости о того, как трактовать фасеты.

S>Ну, мы вроде сошлись на том, что один класс может принадлежать нескольким фасетам, нет?
Интуитивно — понятно, на практике — мне неясно, как тогда ссылаться на класс.

0>>У нас "antivirus" не на прямую использует "antirivus.updater", они оба используются другими классами, оркестрирующими их работу.

S>Тогда в неймспейсе "antirivus.updater" должна остаться только та часть, что знает об антивирусе и она должна быть унаследована от базового класса/интерфейса.
Хорошо. А почему бы не поместить эту часть в неймспейс updater.antivirus?

S>Я вообще-то пытался отразить зависимости между компонентами. Если получилась условность — я не угадал, и у вас получается другой граф зависимостей.

Граф тот же, способ его планаризации — другой.

S>Фасеточная способна отразить только часть структуры, но не всю её целиком. Поэтому, если вы отказываетесь от иерархии вы отказываетесь от _явной_ модели софта/архитектуры.

Они пытаются ввести многомерную классификацию. Примерно то же, что и с множественным наследованием. Вот у вас табличка с классами; по горизонтали — слои (DB, UI, BL), по вертикали — функциональные блоки. Никакой неопределённости в помещении того или иного класса в одну из ячеек нет. Есть зато неопределённость в том, как именовать неймспейсы: ui.anitivirus, ui.antispam, или antivirus.ui, antivirus.bl.

Мне неизвестен язык программирования, который бы позволил задать правило "в функциональном неймспейсе могут быть только поднеймспейсы bl, db, и ui". Или хоть как-то гарантировать, что вместо antispam.db не появится какой-нибудь antispam.database, сломав стройную структуру таблички.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Примеры
От: 0x7be СССР  
Дата: 13.03.11 07:33
Оценка: 2 (1)
Здравствуйте, Qbit86, Вы писали:

Q>Реквестирую содержательные примеры, наводящие соображения и прочие промежуточные звенья рассуждений, что привели топик-стартера к вопросу в исходном сабже.

Участвую в разработке серверного антивирусного продукта, который проверяет циркулирующую в информационной системе информацию. Проверка ведется, собственно, антивирусным движком и движком, фильтрующим содержимое (например — спамфильтр). То есть уже две граним: антивирь, антиспам. Далее, проверка может быть осуществлена в двух разных сценариях — по инициативе контролируемой ИС и по нашей инициативе. Вот тебе ещё две грани, причем есть код, который специфичен для всех комбинацией грани из первой пары и из второй, равно как и код, принадлежащий этим граням по отдельности. Далее, базы данных для сканеров надо скачивать: плюс грань "скачивалка". Разработка ведется на .net с привлечением нативных компонентов и интерфейсов с ИС: плюс грань "интероп". Ещё для этих подсистем есть свой гуй, который тоже суть грань. И много ещё чего есть, все лень писать.

Сначала в проекте не было системного подхода к организации сборок и пространств имен, что привело к анархии в этом вопросе и большой энтропии в структуре проекта. Потом это надоело, все было пересмотрено, были выделены грани (означенные выше и не только), они были кодифицированы и занесены в инструкцию. Отображение на иерархическую структуру делалось так: все грани разранжировали и при необходимости составить путь к конкретному компоненту пользовались этим ранжированием. Например, решили, что "ативтирус" приоритетнее, чем "скачивалка", значит скачивалка для антивируса будет обзываться "антивирус.скачивалка". А код "просто скачивалки", будет располагаться в пространстве имен "скачивалка", ибо более приоритетной грани у неего нет. И грань "интероп" наименее приоритетная, так что интероп для скачивалки будет лежать в "скачивалка.интероп". На основании этого был проведен Большой Рефакторинг.

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

Достаточно содержательный пример получился?
Re: Namespaces vs. Tags (Facets)
От: barn_czn  
Дата: 15.03.11 15:58
Оценка: -1
Даже в примеры не хочу вникать . Ересь эта фасеточная ваша модель.
Программист всегда будет конструировать структруры (фасет ваш тоже структура в конечном итоге).
А самая удобная модель структуры — дерево. Не произвольный граф, а именно дерево.
Вы можете построить любую структуру поверх дерева (заюзав тэги, идентификаторы).
Re[2]: Namespaces vs. Tags (Facets)
От: x-code  
Дата: 17.03.11 11:03
Оценка: +1
Здравствуйте, barn_czn, Вы писали:

_>Даже в примеры не хочу вникать . Ересь эта фасеточная ваша модель.

_>Программист всегда будет конструировать структруры (фасет ваш тоже структура в конечном итоге).
_>А самая удобная модель структуры — дерево. Не произвольный граф, а именно дерево.
_>Вы можете построить любую структуру поверх дерева (заюзав тэги, идентификаторы).

Не ересь, а весьма перспективное направление. Парадигма АОП кстати в некотором роде близка этой модели, только там речь идет о сквозной функциональности внутри функций, а здесь — о сквозной группировке единиц кода более высокого уровня.
Я лично думаю над тем, как можно такую фасеточную модель внедрить в язык программирования.
Дерево конечно удобно, но задача — сделать удобным использование таких моделей. Очевидно, что пользоваться произвольными графами менее удобно, чем деревьями, но вот теги по уровню удобства сравнимы с деревьями, так что думать надо в направлении "как использовать теги вместо namespaces".
Re[4]: Примеры
От: 0x7be СССР  
Дата: 13.03.11 08:33
Оценка:
Здравствуйте, Sinix, Вы писали:

S>А почему вы думаете, что с тегами будет проще? Проблема — не в способе описания, а в том, что вы пытаетесь применить средство самодокументирования к области, для которой вы ещё не придумали способ классификации.

Нет, способ классификации мы придумали
Только он получился фасеточный, а не иерархический

S>Если вы перейдёте к меткам, то фактически будете поощрять дальнейшую энтропию. Всё, что вы получите — множество равноправных иерархий вместо одной, но частично кривой. Посмотрите на самые удачные примеры тегирования — wiki и stackowerflow. Как, удобно?

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

S>Summary: если бардак не автоматизируется, неймспейсы винить как-то глупо

S>Если вернуться к примеру с антивирусом — почему нельзя было пойти самым простым путём — завести
S>YourCompany.Antivirus, YourCompany.Helpers.Downloader, YourCompany.Helpers.Interop etc?
S>Зачем вводить двустороннюю связность в именование и в архитектуру проекта? У вас что, скачивалка зависит каким-либо образом от антивируса?
По-моему ты не очень внимательно прочитал мой пример. Или я его криво описал
Да, есть модуль "скачивалка", а есть модули, адаптирующие его к антивирю и антисмаму, ибо есть у них в плане качения баз своя специфика. То есть модули, которые связаны И со скачивалкой И с антивирусом/антиспамом.
Куда их помещать в единой иерархической структуре?

S>А интероп использует API скачивалки? Зачем их смешивать?

А интероп — это вообще отдельный аспект подсистемы, в которой задействован нативный компонент. То есть свой интероп есть и у антивиря, и у антиспама, и у скачивалки и ещё есть. То есть у нас есть "антивирь.интероп", "антиспам.интероп"... Понятно, что антивирус не имеет никаких дел с интеропом скачивалки.
Re[5]: Примеры
От: x-code  
Дата: 13.03.11 09:09
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>По-моему ты не очень внимательно прочитал мой пример. Или я его криво описал

0>Да, есть модуль "скачивалка", а есть модули, адаптирующие его к антивирю и антисмаму, ибо есть у них в плане качения баз своя специфика. То есть модули, которые связаны И со скачивалкой И с антивирусом/антиспамом.
0>Куда их помещать в единой иерархической структуре?

S>>А интероп использует API скачивалки? Зачем их смешивать?

0>А интероп — это вообще отдельный аспект подсистемы, в которой задействован нативный компонент. То есть свой интероп есть и у антивиря, и у антиспама, и у скачивалки и ещё есть. То есть у нас есть "антивирь.интероп", "антиспам.интероп"... Понятно, что антивирус не имеет никаких дел с интеропом скачивалки.

ИМХО, мысль интересная. У вас есть идеи, как это реализовать на уровне синтаксиса некоего гипотетического языка программирования?
И можно ли это совместить с традиционной иерархической организацией?
Re[6]: Примеры
От: 0x7be СССР  
Дата: 13.03.11 09:13
Оценка:
Здравствуйте, x-code, Вы писали:

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

XC>И можно ли это совместить с традиционной иерархической организацией?
Пока нет, хотя мысли на этот счет крутятся.
Сказать по правде, идею поддержать это на уровне языка я считаю несколько утопической.
В том смысле, что в массы не пойдет, слишком революционное изменение.
Мне более перспективной кажется инструментальная поддержка такого стиля.
Re[6]: Примеры
От: 0x7be СССР  
Дата: 13.03.11 13:25
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Второй вариант как раз и превращается в кучу равноправных классификаторов. Если вы даже промеж себя никак не договоритесь, что куда отнести — как тут помогут фасеты?

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

S>Основное предназначение namespace-ов — самодокументирование, отражение структуры проекта и пояснение назначения его составляющих. Если перейти к меткам, то у нас всё вышеперечисленное отпадает и появляется куча вопросов аля

S>- "[Antivirus].Downloader" и "[AdwareBlocker].Downloader" — это один и тот же класс, или несколько?
S>- Если один — почему он нарушает SRP и делает 2 работы одновременно?
S>- Если он не нарушает, и это просто универсальный класс — каким боком он относится к антивирусу или адблоку?
Это в зависимости о того, как трактовать фасеты.
Например, не возникает же вопросов, один ли класс "Antivirus.Downloader" или "Adblock.Downloader" в традиционных пространствах имен.
Если принять, что совокупность фасетов + имя класса однозначно определяет уникальный класс, то вопросов не будет — это будут однозначно разные классы.
Вообще, если модуль находится строго на стыке двух функциональных областей, то попытка отнести его либо к одной либо к другой все равно приводит к натяжкам. Это фундаментальный недостаток иерархической модели.

S>Для _больших_ проектов:

S>...
S>Для мелких:
S>...
Как вариант. Мы сделали похожим образом — директивно определили, что "antivirus" приоритетное "updater`a" и модули, где пересекаются этих области
помещаем не в "updater.antivirus", а в "antivirus.updater". Но это лишь соглашение, а не объективная реальность.

S>Смысл такого разделения, в том, что _используемый_ компонент не должен ничего знать об остальном коде. Иначе у вас возникает сильная связь между всеми частями проекта: начинаете править downloader под сценарий для антивируса, ломаете адблокер.

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

S>Попробую ещё раз сформулировать свою точку зрения, чтобы не было разночтений:

S>Метки полезны только для поиска. Когда нет структуры, она не отражает действительность, или нет никакого желания в ней разбираться. Предлагать метки как основное решение — мягко говоря, ересь
Я понял Вашу точку зрения, но не согласен с ней. Если несколько обобщить Ваши слова, то получается утверждение, что только иерархическая классификация способна отражать структуру, а фасеточная — нет. Я рассматриваю оба этих метода классификации как равноправные, со своей областью применимости каждый. И в конкретно своей ситуации я констатирую, что фасеточная классификация пригодилась бы мне больше.
Re[7]: Примеры
От: Sinix  
Дата: 13.03.11 13:45
Оценка:
Здравствуйте, 0x7be, Вы писали:

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

Т.е. оба варианта выше не подходят? Невесело вам

0>Это в зависимости о того, как трактовать фасеты.

Ну, мы вроде сошлись на том, что один класс может принадлежать нескольким фасетам, нет?

0>Например, не возникает же вопросов, один ли класс "Antivirus.Downloader" или "Adblock.Downloader" в традиционных пространствах имен.

Да. Потому что неймспейсы не создают двусмысленностей

0>Если принять, что совокупность фасетов + имя класса однозначно определяет уникальный класс, то вопросов не будет — это будут однозначно разные классы.

Ок, интересная идея. Только она убивает расширяемость в зародыше. Потребуется переиспользовать downloader для файрволла — как быть тогда?

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


0>Как вариант. Мы сделали похожим образом — директивно определили, что "antivirus" приоритетное "updater`a" и модули, где пересекаются этих области

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

0>У нас "antivirus" не на прямую использует "antirivus.updater", они оба используются другими классами, оркестрирующими их работу.

Тогда в неймспейсе "antirivus.updater" должна остаться только та часть, что знает об антивирусе и она должна быть унаследована от базового класса/интерфейса.

0>В итоге такой порядок отображения фасетов на пространства имен не более чем условность.

Я вообще-то пытался отразить зависимости между компонентами. Если получилась условность — я не угадал, и у вас получается другой граф зависимостей.

0>Я понял Вашу точку зрения, но не согласен с ней. Если несколько обобщить Ваши слова, то получается утверждение, что только иерархическая классификация способна отражать структуру, а фасеточная — нет.

Фасеточная способна отразить только часть структуры, но не всю её целиком. Поэтому, если вы отказываетесь от иерархии вы отказываетесь от _явной_ модели софта/архитектуры.

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

Пока что не увидел — почему.
Re[8]: Примеры
От: 0x7be СССР  
Дата: 13.03.11 20:00
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, 0x7be, Вы писали:


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

S>Т.е. оба варианта выше не подходят? Невесело вам
Ну, мы нашли командно-административный выход, директивно назначив конкретный способ отображения фасетов на иерархию пространств имен.
Было бы приятно, если бы некая тулза ещё бы и присматривала за этим в автоматическом режиме.

S>Ну, мы вроде сошлись на том, что один класс может принадлежать нескольким фасетам, нет?

Да.

S>Ок, интересная идея. Только она убивает расширяемость в зародыше.

S>Потребуется переиспользовать downloader для файрволла — как быть тогда?
S>...
S>Я же говорю — вы отражаете в именах обратные зависимости. Получается, что у вас downloader зависит и от антивируса, и от адблока и т.д. и т.п. Хотя в идеальном случае он должен быть просто вспомогательным классом, у которого ровно одна ответственность — скачивать данные.
Не уловил. Впрочем, см. ниже.

S>Я вообще-то пытался отразить зависимости между компонентами. Если получилась условность — я не угадал, и у вас получается другой граф зависимостей.

Боюсь у нас тут некоторый miscommunication по поводу нашей архитектуры. Ниже попробую снова изложить.

S>Фасеточная способна отразить только часть структуры, но не всю её целиком.

S>Поэтому, если вы отказываетесь от иерархии вы отказываетесь от _явной_ модели софта/архитектуры.
Ну, мы говорим всего лишь об организации кода, а это лишь малая часть архитектуры

S>Пока что не увидел — почему.

Ок, второй заход. Опишу минимальный набор компонентов, пригодный для иллюстрации идеи:
Есть следующие компоненты:
Updater — реализует в себе общую для всех часть функционала обновления.
AntivirusScanner — антивирусный сканер, использует Updater.
AntispamScanner — антиспамовый сканер, использует Updater.
AntivirusUpdater — антивирусный обновитель.
AntispamUpdater — антиспамовый обновитель.

Тут мы наблюдаем 4 фасета: Updater, Antivirus, Antispam, Scanner.
Фишка в том, что, например, AntivirusUpdater может быть расположен пространстве имен двумя РАВНОПРАВНЫМИ способами:
1. Antivirus.Updater.AntivirusUpdater.
2. Updater.Antivirus.AntivirusUpdater.
(ПРИМЕЧАНИЕ: порядок слов в самом идентификаторе AntivirusUpdater следует из правил английского языка )
Сейчас волевым решением выбран первый вариант, но объективно он ничем не лучше.
Это исключительно соглашение, что бы было "безобразно, но единообразно".

Далее, если мы захотим заиметь ещё один вид сканера, то у нас добавляется ещё один фасет.
Пусть это будет какая-нибудь порнорезалка. Естественным образом у нас появляется фасет Pornbuster, и компоненты PornbusterScanner и PornbusterUpdater.
Никаких "криминальных" зависимостей между компонентами, которые бы зарубили нам расширяемость, тут не наблюдается.

Так лучше понятно?
Re: Namespaces vs. Tags (Facets)
От: GarryIV  
Дата: 14.03.11 06:35
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


0>Собственно, вопрос: как Вы думаете, имеет ли право на полную и насыщенную пользой жизнь идея организации программ через систему граней/тэгов?

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

Если над проектом работает несколько человек, пишутся правила, которых надо придерживатся и все норм.
Что касается тегов, а как ты предполагаешь их использовать?
В существующих языках обычно используют namespace для определения к какому блоку функционала относится класс и суффиксы для доп тегов.
Например java.util.concurrent.ExecutorService. Имя пакета java.util.concurrent говорит с том что классы в нем предназначены для упрощения работы с многопоточностью а Service определяет роль класса.
Так же в качестве тегов используют метаинформацию (аннотации\атрибуты) — это если надо иметь возможность для оперирования или в рантайме.
WBR, Igor Evgrafov
Re: Namespaces vs. Tags (Facets)
От: Kefir http://www.hippoedit.com
Дата: 14.03.11 14:02
Оценка:
Здравствуйте, 0x7be:

гляньте code bubles, это вариант с реализацией в IDE.
Re[2]: Namespaces vs. Tags (Facets)
От: 0x7be СССР  
Дата: 15.03.11 05:13
Оценка:
Здравствуйте, Kefir, Вы писали:

K>гляньте code bubles, это вариант с реализацией в IDE.

Занятная штука, но что-то не увидел там именно фасеточности/тэговости.
Может плохо смотрел
Re: Namespaces vs. Tags (Facets)
От: Константин Л. Франция  
Дата: 15.03.11 11:09
Оценка:
Здравствуйте, 0x7be, Вы писали:

[]

а можно живой пример facets?
Re[2]: Namespaces vs. Tags (Facets)
От: 0x7be СССР  
Дата: 15.03.11 11:20
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>а можно живой пример facets?

здесь
Автор: 0x7be
Дата: 13.03.11
Re[9]: Примеры
От: Константин Л. Франция  
Дата: 15.03.11 11:48
Оценка:
Здравствуйте, 0x7be, Вы писали:

дико извиняюсь, но по-моему вы только создаете себе проблемы.
нету у вас никаких проблем с namespaces, у вас есть проблемы с зависимостями между типами.

[]

S>>Пока что не увидел — почему.

0>Ок, второй заход. Опишу минимальный набор компонентов, пригодный для иллюстрации идеи:
0>Есть следующие компоненты:
0>Updater — реализует в себе общую для всех часть функционала обновления.
0>AntivirusScanner — антивирусный сканер, использует Updater.
0>AntispamScanner — антиспамовый сканер, использует Updater.
0>AntivirusUpdater — антивирусный обновитель.
0>AntispamUpdater — антиспамовый обновитель.

0>Тут мы наблюдаем 4 фасета: Updater, Antivirus, Antispam, Scanner.

0>Фишка в том, что, например, AntivirusUpdater может быть расположен пространстве имен двумя РАВНОПРАВНЫМИ способами:
0>1. Antivirus.Updater.AntivirusUpdater.
0>2. Updater.Antivirus.AntivirusUpdater.

ну и в чем проблема? зачем тут какие-то фасеты?

ну и расположи либо в 1 либо в 2, исходя из архитектуры приложения и наименьшей связности кода.

[]


namespace <AVCo>.<Product>.Client.Common.Updates
{
    class Updater {}
}

namespace <AVCo>.<Product>.Client.Scanners
{
    class AntivirusScanner  {}

    class AntispamScanner {}
}

namespace <AVCo>.<Product>.Client.Scanners.Updates
{
    class AntivirusUpdater {}

    class AntispamUpdater {}
}


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

Не то чтобы идея совсем неинтересна, просто с мотивацией что-то не то.
Re[2]: Namespaces vs. Tags (Facets)
От: 0x7be СССР  
Дата: 15.03.11 16:14
Оценка:
Здравствуйте, barn_czn, Вы писали:

_>Даже в примеры не хочу вникать . Ересь эта фасеточная ваша модель.

"Не читал, но осуждаю"

_>Программист всегда будет конструировать структруры (фасет ваш тоже структура в конечном итоге).

Согласен.

_>А самая удобная модель структуры — дерево. Не произвольный граф, а именно дерево.

Спорно. Какие Ваши аргументы?

_>Вы можете построить любую структуру поверх дерева (заюзав тэги, идентификаторы).

Можем, но если предметная область не вписывается в иерархическую модель, то зачем себя насиловать?
Re[3]: Namespaces vs. Tags (Facets)
От: Sinclair Россия https://github.com/evilguest/
Дата: 18.03.11 07:03
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Не ересь, а весьма перспективное направление. Парадигма АОП кстати в некотором роде близка этой модели, только там речь идет о сквозной функциональности внутри функций, а здесь — о сквозной группировке единиц кода более высокого уровня.

XC>Я лично думаю над тем, как можно такую фасеточную модель внедрить в язык программирования.
XC>Дерево конечно удобно, но задача — сделать удобным использование таких моделей. Очевидно, что пользоваться произвольными графами менее удобно, чем деревьями, но вот теги по уровню удобства сравнимы с деревьями, так что думать надо в направлении "как использовать теги вместо namespaces".
Вижу два аспекта:
1. Объявления. Как объяснить компилятору, в каких фасетах присутствует описываемый класс.
2. Доступ. Как объяснить компилятору, из какого фасета брать классы. Тем более, что не очень понятно, то ли имеется в виду "всё из antivirus, плюс всё из db", или "всё из пересечения antivirus и bd".
3. Как избежать взрыва мозга.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Namespaces vs. Tags (Facets)
От: jazzer Россия Skype: enerjazzer
Дата: 25.03.11 08:45
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вижу два аспекта:

S>1. Объявления. Как объяснить компилятору, в каких фасетах присутствует описываемый класс.
В C++ для этого используется техника traits.

S>2. Доступ. Как объяснить компилятору, из какого фасета брать классы. Тем более, что не очень понятно, то ли имеется в виду "всё из antivirus, плюс всё из db", или "всё из пересечения antivirus и bd".

Что значит — брать? Опять же, это можно сделать через шаблоны и traits, благо в классах могут быть члены-типы (те самые классы, которые нужно "брать").

S>3. Как избежать взрыва мозга.

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Namespaces vs. Tags (Facets)
От: SV.  
Дата: 25.03.11 09:33
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


Неймспейсы и так почти что теги. Вы можете взять свой класс и поместить его в любой неймспейс без "переписывания неймспейса", и существующего кода. Это то же самое, что пометить его произвольным тегом. Тегов может быть много, а неймспейс один, это правда, но контрактный тег (то, что вы называете "гранью") и должен быть один. Класс не должен выполнять несколько контрактов, это азбука ООП. Каждый контракт должен быть четко определен и относиться к одной области-грани (иначе, у вас декомпозиция корявая). То есть, остальные теги — это уточнение деталей и лучше их реализовать отдельно (через атрибуты).

Как правильно написали выше, без примеров это обсуждать бессмысленно. Нужен класс, который с равным основанием можно отнести к двум неймспейсам сразу. Не обязательно ваш пример, любой другой пойдет. Берусь показать, что это в каждом случае плохая декомпозиция.
Re[2]: Азбука ООП
От: Qbit86 Кипр
Дата: 25.03.11 09:40
Оценка:
Здравствуйте, SV., Вы писали:

SV.>Класс не должен выполнять несколько контрактов, это азбука ООП.


Это не азбука ООП, это ваши досужие заключения.
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: Азбука ООП
От: SV.  
Дата: 25.03.11 09:52
Оценка:
Здравствуйте, Qbit86, Вы писали:

SV.>>Класс не должен выполнять несколько контрактов, это азбука ООП.

Q>Это не азбука ООП, это ваши досужие заключения.

Беру это утверждение назад: некорректно сформулировал. Если каждый интерфейс считать за контракт, то, конечно, это глупость. Я имел в виду, что класс должен решать одну четко определенную функциональную задачу, в противном случае его надо разбить. Если и с этм несогласны, то сразу приводите контрпример.
Re[2]: Namespaces vs. Tags (Facets)
От: 0x7be СССР  
Дата: 25.03.11 10:15
Оценка:
Здравствуйте, SV., Вы писали:

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

Посмотрите здесь
Автор: 0x7be
Дата: 13.03.11
в конце сообщения.
Интересны Ваши комментарии.
Re[9]: Примеры
От: jazzer Россия Skype: enerjazzer
Дата: 25.03.11 10:38
Оценка:
Здравствуйте, 0x7be, Вы писали:

S>>Пока что не увидел — почему.

0>Ок, второй заход. Опишу минимальный набор компонентов, пригодный для иллюстрации идеи:
0>Есть следующие компоненты:
0>Updater — реализует в себе общую для всех часть функционала обновления.
0>AntivirusScanner — антивирусный сканер, использует Updater.
0>AntispamScanner — антиспамовый сканер, использует Updater.
0>AntivirusUpdater — антивирусный обновитель.
0>AntispamUpdater — антиспамовый обновитель.

0>Тут мы наблюдаем 4 фасета: Updater, Antivirus, Antispam, Scanner.

0>Фишка в том, что, например, AntivirusUpdater может быть расположен пространстве имен двумя РАВНОПРАВНЫМИ способами:
0>1. Antivirus.Updater.AntivirusUpdater.
0>2. Updater.Antivirus.AntivirusUpdater.
0>(ПРИМЕЧАНИЕ: порядок слов в самом идентификаторе AntivirusUpdater следует из правил английского языка )
0>Сейчас волевым решением выбран первый вариант, но объективно он ничем не лучше.
0>Это исключительно соглашение, что бы было "безобразно, но единообразно".

0>Далее, если мы захотим заиметь ещё один вид сканера, то у нас добавляется ещё один фасет.

0>Пусть это будет какая-нибудь порнорезалка. Естественным образом у нас появляется фасет Pornbuster, и компоненты PornbusterScanner и PornbusterUpdater.
0>Никаких "криминальных" зависимостей между компонентами, которые бы зарубили нам расширяемость, тут не наблюдается.

0>Так лучше понятно?


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

Да, а язык какой?
Если это С++, в котором можно иметь члены-типы, то можно писать так:
// пусть мы стартуем от более-менее "главных" вещей
class Antivirus {
  class Scanner;
  class Updater;
};

class Antispam {
  class Scanner;
  class Updater;
};

class Pornbuster {
  class Scanner;
  class Updater;
};

// теперь грани
struct Updater {
  typedef Antivirus::Updater Antivirus;
  typedef Antispam::Updater Antispam;
  typedef Pornbuster::Updater Pornbuster;
};

struct Scanner {
  typedef Antivirus::Scanner Antivirus;
  typedef Antispam::Scanner Antispam;
  typedef Pornbuster::Scanner Pornbuster;
};


так как в С++ typedef — это не новый тип, а алиас на уже существующий тип, то ты теперь можешь писать как угодно, хоть Antivirus::Updater, хоть Updater::Antivirus — это будет один и тот же класс.

Из этого можно извлечь немалый профит, кстати, так как Updater — это сам по себе тип, которым можно, например, параметризовать какой-нть шаблон, и он автоматом подхватит именно то, что нужно.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Namespaces vs. Tags (Facets)
От: SV.  
Дата: 25.03.11 10:38
Оценка:
Здравствуйте, 0x7be, Вы писали:

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

0>Посмотрите здесь
Автор: 0x7be
Дата: 13.03.11
в конце сообщения.

0>Интересны Ваши комментарии.

Тут мы наблюдаем 4 фасета: Updater, Antivirus, Antispam, Scanner.
Фишка в том, что, например, AntivirusUpdater может быть расположен пространстве имен двумя РАВНОПРАВНЫМИ способами:
1. Antivirus.Updater.AntivirusUpdater.
2. Updater.Antivirus.AntivirusUpdater.
(ПРИМЕЧАНИЕ: порядок слов в самом идентификаторе AntivirusUpdater следует из правил английского языка )
Сейчас волевым решением выбран первый вариант, но объективно он ничем не лучше.
Это исключительно соглашение, что бы было "безобразно, но единообразно".


Это? AntivirusUpdater — класс? Я вижу два варианта:

1. На самом деле класс НЕ AntivirusUpdater. То есть, он может использоваться для обновления чего угодно, может взаимозаменяться с BITS, а написан просто потому, чтоб не привязываться к конкретным платформам типа COM. В этом случае класс надо переименовать в SoftwareUpdater, а неймспейс под него завести типа ServerIO, Updating или Steam

2. Это в самом деле AntivirusUpdater. Ваше приложение-антивирус должно обновляться не так, как другой софт. Есть какие-то очень важные нюансы. (Допустим даже, что AntivirusUpdater использует SoftwareUpdater). В этом случае Antivirus.Updater.AntivirusUpdater не равноправен Updater.Antivirus.AntivirusUpdater, поскольку Updater — компонент антивируса, а не наоборот.
Re[4]: Namespaces vs. Tags (Facets)
От: mrTwister Россия  
Дата: 25.03.11 20:47
Оценка:
Здравствуйте, SV., Вы писали:

SV.>2. Это в самом деле AntivirusUpdater. Ваше приложение-антивирус должно обновляться не так, как другой софт. Есть какие-то очень важные нюансы. (Допустим даже, что AntivirusUpdater использует SoftwareUpdater). В этом случае Antivirus.Updater.AntivirusUpdater не равноправен Updater.Antivirus.AntivirusUpdater, поскольку Updater — компонент антивируса, а не наоборот.


А как на счет сфокусированности (cohesion) кода? Например, если антивирус — это независимый компонент, который вообще ничего не знает об апдейтере? При этом есть апдейтер антивируса, который умеет апдейтить именно антивирус (специфичная логика) и тесно связан с общим кодом обновления вместе с другими апдейтерами. То, что ты предлагаешь — это по сути когда мы нечто делаем составной частью некоторого другого компонента, при том, что сам этот компонент вообще ничего не знает о своей "составной части". Это нормально? Ну то есть примерно как автомобильную заправку назвать составной частью автомобиля.
лэт ми спик фром май харт
Re[5]: Namespaces vs. Tags (Facets)
От: SV.  
Дата: 26.03.11 12:03
Оценка:
Здравствуйте, mrTwister, Вы писали:

SV.>>2. Это в самом деле AntivirusUpdater. Ваше приложение-антивирус должно обновляться не так, как другой софт. Есть какие-то очень важные нюансы. (Допустим даже, что AntivirusUpdater использует SoftwareUpdater). В этом случае Antivirus.Updater.AntivirusUpdater не равноправен Updater.Antivirus.AntivirusUpdater, поскольку Updater — компонент антивируса, а не наоборот.


T>А как на счет сфокусированности (cohesion) кода? Например, если антивирус — это независимый компонент, который вообще ничего не знает об апдейтере? При этом есть апдейтер антивируса, который умеет апдейтить именно антивирус (специфичная логика) и тесно связан с общим кодом обновления вместе с другими апдейтерами. То, что ты предлагаешь — это по сути когда мы нечто делаем составной частью некоторого другого компонента, при том, что сам этот компонент вообще ничего не знает о своей "составной части". Это нормально? Ну то есть примерно как автомобильную заправку назвать составной частью автомобиля.


Вообще-то, я предполагал, что антивирус — это приложение, которое дергает апдейтер по команде из GUI. Если нет, и общение приложения и апдейтера происходит только через конфиги, то это другой случай. Вот такой:

class Antivirus.Updater.AntivirusUpdaterService; // Класс апдейтера
class Antivirus.Core.Application; // Класс "независимого компонента, который вообще ничего не знает об апдейтере".


Еще раз, я полагаю, что в функциональном аспекте иерархии ВСЕГДА годятся. Иерархическая неоднозначность идет уровнем ниже (то есть, на уровне атрибутов). Если кто-то приведет контрпример, это будет весьма интересно.
Re[6]: Namespaces vs. Tags (Facets)
От: mrTwister Россия  
Дата: 26.03.11 12:27
Оценка:
Здравствуйте, SV., Вы писали:

SV.>
SV.>class Antivirus.Updater.AntivirusUpdaterService; // Класс апдейтера
SV.>class Antivirus.Core.Application; // Класс "независимого компонента, который вообще ничего не знает об апдейтере".
SV.>


Прекрасно, а теперь посмотрим на все это с несколько другой точки зрения, а именно с кода апдейтера. Допусти есть не только апдейтер антивируса, но и апдейтер чего-то еще, есть базовый функционал для всех апдейтеров, есть планировщик задач апдейтера — то есть куча классов, у которых друг с другом довольно высокие cohesion и coupling. В предложенном тобой решении эти классы оказываются сильно разбросаны по иерархии и находятся друг от друга далеко. В этом и проблема. Если я правильно понял топик стартера, то он бы хотел в одном случае посмотреть на иерархию кода, который так или иначе связан с обновлением (какие есть классы, какие зависимости между ними, у кого какая ответственность и так далее), а в другом случае он бы хотел посмотреть на иерархию кода, который так или иначе связан с антивирусом. И в обоих случаях ему было бы удобно работать с разными иерархиями.
лэт ми спик фром май харт
Re[7]: Namespaces vs. Tags (Facets)
От: SV.  
Дата: 26.03.11 14:14
Оценка:
Здравствуйте, mrTwister, Вы писали:

SV.>>
SV.>>class Antivirus.Updater.AntivirusUpdaterService; // Класс апдейтера
SV.>>class Antivirus.Core.Application; // Класс "независимого компонента, который вообще ничего не знает об апдейтере".
SV.>>


T>Прекрасно, а теперь посмотрим на все это с несколько другой точки зрения, а именно с кода апдейтера. Допусти есть не только апдейтер антивируса, но и апдейтер чего-то еще, есть базовый функционал для всех апдейтеров, есть планировщик задач апдейтера — то есть куча классов, у которых друг с другом довольно высокие cohesion и coupling. В предложенном тобой решении эти классы оказываются сильно разбросаны по иерархии и находятся друг от друга далеко. В этом и проблема.


Как раз про это я хотел написать, и даже начал:

T>и тесно связан с общим кодом обновления вместе с другими апдейтерами
Забыл добавить. Вот эта тесная связь для меня не является основанием помещать наш апдейтер в неймспейс "с другими апдейтерами".


В википедии написано, что неймспейс — это контекст для идентификаторов, и я с этим горячо согласен. Контекст, как я понимаю, служит для разрешения конфликтов и для функциональной классификации (апдейтер в контексте антивируса — функциональная часть антивируса). Спрашивается, причем здесь cohesion и coupling? Давайте рассуждать методом доведения до абсурда. string используется во множестве классов. Лежит, однако, в System. В этом тоже какая-то проблема? Допустим, вы делаете свой string, какой-нибудь... ммм... с автопереводом. Он активно использует System.String для хранения и обработки. Будете ли вы помещать его тоже в System? Технических препятствий-то нет. Студия по рукам не надает.

Апдейтер антивируса, не смотря на связность и связанность с другими апдейтерами, имеет антивирусный контекст.

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

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


Это решительно невозможно обсуждать без примеров. То, что было приведено — не примеры, а так, заготовка для болтологии. Если у нас три класса — базовый универсальный Updater, специализированный AntivirusUpdater, и Application, я уже написал, как бы я сделал:

class System.Updating.BaseUpdaterService; // Базовый класс апдейтера из какого-то фреймворка.
class Antivirus.Updater.AntivirusUpdaterService : System.Updating.BaseUpdaterService; // Специализированный класс апдейтера.
class Antivirus.Core.Application : System.Application; // Класс "независимого компонента, который вообще ничего не знает об апдейтере".


Соответственно, если вы не согласны, или покажите перепаковку этих трех классов, или добавьте в пример новые классы, которые покажут не... кузявость единственной неймспейсовской иерархии.
Re[5]: Namespaces vs. Tags (Facets)
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.03.11 07:59
Оценка:
Здравствуйте, jazzer, Вы писали:

S>>2. Доступ. Как объяснить компилятору, из какого фасета брать классы. Тем более, что не очень понятно, то ли имеется в виду "всё из antivirus, плюс всё из db", или "всё из пересечения antivirus и bd".

J>Что значит — брать?
Значит выполнять name lookup. Вот я пишу Console.WriteLine(). Какой Console имеется в виду? Из System.*?

S>>3. Как избежать взрыва мозга.

J>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Примеры
От: jazzer Россия Skype: enerjazzer
Дата: 27.03.11 13:44
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Мне неизвестен язык программирования, который бы позволил задать правило "в функциональном неймспейсе могут быть только поднеймспейсы bl, db, и ui". Или хоть как-то гарантировать, что вместо antispam.db не появится какой-нибудь antispam.database, сломав стройную структуру таблички.


В С++ можно вместо неймспейсов пользоваться просто структурами и членами-типами в них. А в структурах как раз можно все это гарантировать.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Namespaces vs. Tags (Facets)
От: jazzer Россия Skype: enerjazzer
Дата: 27.03.11 13:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>>2. Доступ. Как объяснить компилятору, из какого фасета брать классы. Тем более, что не очень понятно, то ли имеется в виду "всё из antivirus, плюс всё из db", или "всё из пересечения antivirus и bd".

J>>Что значит — брать?
S>Значит выполнять name lookup. Вот я пишу Console.WriteLine(). Какой Console имеется в виду? Из System.*?
Ну информация же о фасете/ах откуда-то все же доступна? Или вообще все с потолка?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: Namespaces vs. Tags (Facets)
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.03.11 16:22
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ну информация же о фасете/ах откуда-то все же доступна? Или вообще все с потолка?

Понятно, что доступна. Как ей пользоваться?
В случае плоского дерева я пишу
using Namespace.Subnamespace;

и в область видимости влетает всё, что нужно.
В случае фасетов что будет происходить если я пишу
using Updater;
using Antivirus;

? Войдут ли в область видимости все классы из Updater (включая AntispamUpdater), все классы из Antivirus (включая AntivirusChecker) или только AntivirusUpdater и все остальные из обоих фасетов?
Или надо писать

using Updater & Antivirus;
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Namespaces vs. Tags (Facets)
От: jazzer Россия Skype: enerjazzer
Дата: 28.03.11 11:09
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


J>>Ну информация же о фасете/ах откуда-то все же доступна? Или вообще все с потолка?

S>Понятно, что доступна. Как ей пользоваться?
S>В случае плоского дерева я пишу
S>
S>using Namespace.Subnamespace;
S>

S>и в область видимости влетает всё, что нужно.
А, так тебе нужно, чтоб именно using работал
Мне вот вполне явного указания фасета хватит.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: Namespaces vs. Tags (Facets)
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.03.11 22:07
Оценка:
Здравствуйте, jazzer, Вы писали:

S>>и в область видимости влетает всё, что нужно.

J>А, так тебе нужно, чтоб именно using работал
J>Мне вот вполне явного указания фасета хватит.
И как именно это будет выглядеть?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: Namespaces vs. Tags (Facets)
От: jazzer Россия Skype: enerjazzer
Дата: 29.03.11 05:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


S>>>и в область видимости влетает всё, что нужно.

J>>А, так тебе нужно, чтоб именно using работал
J>>Мне вот вполне явного указания фасета хватит.
S>И как именно это будет выглядеть?
Фасет1::Класс1, а как иначе?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[11]: Namespaces vs. Tags (Facets)
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.03.11 15:09
Оценка:
Здравствуйте, jazzer, Вы писали:

S>>И как именно это будет выглядеть?

J>Фасет1::Класс1, а как иначе?
Почему-то fully qualified names не прижились. Везде, где есть неймспейсы, есть и возможность оптового импорта.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.