Данные, контекст и взаимодействие - Data, context and interaction

Данные, контекст и взаимодействие (DCI) - это парадигма, используемая в компьютерном программном обеспечении для программирования систем коммуникации объекты. Его цели:

  • Чтобы улучшить читаемость объектно-ориентированный код, придавая поведению системы первоклассный статус;
  • Чисто отделить код для быстро меняющегося поведения системы (что за система делает) по сравнению с медленно меняющимся базовые знания (что за система является) вместо того, чтобы объединять оба в одном интерфейсе класса;
  • Чтобы помочь разработчикам программного обеспечения рассуждать о состоянии и поведении на уровне системы, а не только о состоянии и поведении объекта;
  • Поддерживать объектный стиль мышления, близкий к ментальным моделям программистов, а не классовый стиль мышления, который затмил объектное мышление на раннем этапе истории объектно-ориентированных языков программирования.

Парадигма разделяет модель предметной области (данные из сценарии использования (контекст) и роли, которые объекты play (взаимодействие). DCI дополняет модель – представление – контроллер (MVC). MVC как язык шаблонов до сих пор используется для разделения данных и их обработки от представления.

Описание

Данные

Данные остаются "то, что система является. " данные Часть архитектуры DCI - это (относительно) статическая модель данных с отношениями. Дизайн данных обычно кодируется как обычные классы, которые представляют базовую структуру предметной области системы. Эти классы едва ли являются интеллектуальными данными, и им явно не хватает функциональности, присущей поддержке какого-либо конкретного вариант использования. Эти классы обычно инкапсулируют физическое хранилище данных. Эти данные реализуют информационную структуру, которая исходит из ментальной модели конечных пользователей, экспертов в предметной области, программистов и других люди в системе. Они могут близко соответствовать модельным объектам MVC.

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

Объекты данных - это экземпляры классов, которые могут происходить из предметно-ориентированный дизайн, и такие классы могут использовать отношения подтипов для организации данных предметной области. Хотя в конечном итоге DCI сводится к классам, она отражает вычислительную модель, в которой преобладает объектное мышление, а не классовое мышление. Следовательно, когда мы думаем о «данных» в DCI, это означает больше думать об экземплярах во время выполнения, чем о классах, из которых они были созданы.

Контекст

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

Каждый контекст представляет один или несколько вариантов использования. Объект контекста создается для каждого исполнения варианта использования, за который он отвечает. Его основная задача - идентифицировать объекты, которые будут участвовать в варианте использования, и назначить им роли, которые выполняют этот вариант использования через свои обязанности. Роль может содержать методы, и каждый метод является небольшой частью логики алгоритма, реализующего вариант использования. Методы ролей выполняются в контексте объекта, который выбран контекстом для воспроизведения этой роли для текущего применения варианта использования. Привязки ролей к объекту, которые происходят в контексте, можно противопоставить полиморфизму народного объектно-ориентированного программирования. Общая бизнес-функциональность - это сумма сложных динамических сетей методов, децентрализованных в различных контекстах и ​​их ролей.

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

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

Взаимодействие

Взаимодействие - это то, "что система делает. »Взаимодействие реализовано в виде ролей, которые играют объекты во время выполнения. Эти объекты объединяют состояние и методы объекта данных (домена) с методами (но без состояния, поскольку роли не имеют состояния) одной или нескольких ролей. хороший стиль DCI, роль обращается к другому объекту только с точки зрения его (бездетной) роли. Существует специальная роль, называемая себя который привязывается к объекту, играющему текущую роль. Код внутри метода роли может вызывать метод на себя и тем самым вызвать метод части данных текущего объекта. Один любопытный аспект DCI состоит в том, что эти привязки гарантированно будут на месте только во время выполнения (с использованием различных подходов и соглашений; Шаблоны C ++ может использоваться для гарантии успешной привязки). Это означает, что взаимодействия, методы ролей, общий. Фактически, некоторые реализации DCI используют универсальные шаблоны или шаблоны для ролей.

Роль - это программная конструкция без сохранения состояния, которая соответствует ментальной модели конечного пользователя некоторого объекта в системе. Роль представляет собой набор обязанностей. В то время как обычное объектно-ориентированное программирование говорит об объектах или классах как о множестве обязанностей, DCI приписывает их ролям. У объекта, участвующего в варианте использования, есть обязанности: те, которые он берет на себя в результате выполнения определенной роли. В большинстве современных языков программирования есть способ выражать роли и выражать внедрение методов ролей в объекты, а методы реализации различаются в зависимости от языка. Инъекция может быть полностью динамической во время выполнения на таких языках, как Рубин и Python; он более статичен на таких языках, как Болтовня -Писк, Scala и C ++. Среда программирования Qi4j предлагает способ выразить внедрение метода роли в объекты Java.[1] Java 8 метод по умолчанию на интерфейсах может использоваться для реализации ролей безопасным способом.

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

Отличительные черты DCI

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

Объектно-ориентированная программа - это сложная и динамичная сеть объектов в том же смысле, в каком отношения между объектами реального мира сложны и динамичны. Рассмотрим официанта в ресторане. Сам официант представляет собой сложный объект, который можно рассматривать по-разному: как моего Официанта (например, который описывает сегодняшнее меню и принимает мой заказ), как Сотрудник ресторана (с определенной зарплатой и рабочим временем) и как Человек в ресторане (ограничение по вместимости - 150 человек). Если бы класс Waiter был написан так, чтобы уловить реальную сущность Waiters (в этом и заключается суть объектной ориентации), он должен был бы быть очень сложным для поддержки всех этих точек зрения.

В DCI эти различные точки зрения включены в роли. Во время выполнения роль является идентификатором объекта. Во время принятия вариант использования (подобно Подавать вино) Ролевой официант однозначно идентифицирует отдельный объект в любой момент времени. Вы можете возразить, что за столом может быть несколько официантов. Однако они могут отличаться в своих обязанностях в вариант использования, например, в именах ролей HeadWaiter и Busboy. Даже если их обязанности идентичны, они все равно будут описаны как «Официант-1» и «Официант-2» или как отдельные (именованные) элементы вектора «Официант», если кто-то намеревается написать для них программное обеспечение. Таким образом, такая роль, как HeadWaiter, становится идентификатором, дескриптором, с помощью которого объекты ссылаются друг на друга в вариант использования.

DCI распознает официанта как объект, а не, скажем, композицию из частей "Сотрудник", "Официант" и "Личность". Объект имеет свою индивидуальность, не зависящую от вариант использования; это аспект данных DCI. Роли представляют собой псевдонимы для своих объектов, но никогда не являются отдельными объектами; это вызовет самостоятельная шизофрения. В этом смысле каждый официант - это homo sapiens. Это элементарная часть системы официанта. У объекта есть много возможных идентичностей в зависимости от вариант использования он задействован; это проявляется в идентификаторах ролей, которые являются частью аспекта взаимодействия DCI. Это (обычно более интересная) часть того, что делает система. Однако в DCI есть только один объект который несет обе эти точки зрения во время выполнения. Эти перспективы могут быть сгруппированы по-разному во время кодирования. В коде преобладают вариант использования структура, которая пересекает объекты и которая также является частью аспекта взаимодействия DCI.

DCI позволяет объекту выполнять одну или несколько ролей во время вариант использования постановление. Другими словами, объект повторно привязывается к идентификаторам ролей на каждом вариант использования постановление. Эти роли определяют интерфейс, называемый Тип роли. Каждый объект заново «переливается» (в театральном смысле) на каждом вариант использования. Хотя роль привязана только к одному объекту, объект может играть несколько ролей. Например, официант может быть вовлечен в вариант использования для подсчета всех посетителей ресторана во время пожарной инспекции и будет выполнять роль человека, а также роль официанта. Один объект поддерживает поведение обеих ролей, необходимое для выполнения вариант использования.

Таким образом, архитектуры DCI обычно характеризуются следующими свойствами:

  • Модель данных отражает структуру предметной области, а не разделы ее поведения;
  • Объекты динамически принимают роли во время вариант использования постановления;
  • Каждая роль вариант использования воспроизводится объектом, определенным контекстом в начале вариант использования постановление;
  • Сеть взаимодействий между ролями в коде (т.е. во время кодирования) такая же, как и соответствующая сеть объектов во время выполнения;
  • Эти сети потенциально воссоздаются на каждом вариант использования постановление;
  • Роли входят и выходят за рамки с вариант использования жизни, но объекты, которые могут играть эти роли, могут сохраняться в нескольких вариант использования жизни и потенциально могут сыграть множество ролей в течение своей жизни.

Модель исполнения

DCI можно рассматривать как событийно-ориентированное программирование парадигма, где какое-то событие (как человеческий жест в модель-представление-контроллер (MVC) архитектура) триггеры а вариант использования. В вариант использования могут быть недолговечными или долгоживущими. События называются триггеры, и они обрабатываются в среда в который встроен DCI. Эта среда может быть контроллером традиционной архитектуры MVC или любого другого кода системного уровня.

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

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

  1. Контекст сначала находит объекты, которые должны принять участие в этом вариант использования постановление. Эти объекты могут находиться где угодно в среде, в базе данных или создаваться «на лету»; DCI не ограничивает эти объекты. Внутри контекста есть не более одного экземпляра, играющего любую заданную роль в любой момент времени.
  2. Во-вторых, контекст назначает один объект для воспроизведения каждой из своих ролей (хотя один объект часто играет несколько ролей в одном контексте). В сильно динамических языках (Ruby, Python) Контекст вводит методы Role в объект. В большинстве динамических языков любой существующий объект можно попросить сыграть любую роль в любое время (хотя некоторые комбинации объект-роль могут, конечно, не иметь смысла; бессмысленные комбинации объектов и ролей могут привести к СООБЩЕНИЕ НЕ ПОНЯЛ во время выполнения, если был вызван метод Role.) В более статически типизированных языках (Scala, C ++) должна быть какая-то предварительная договоренность, чтобы объект поддерживал методы Role. Например, Scala создает анонимный класс, который сочетает в себе элементарную логику доменного класса с вариант использования логика черта используется для реализации роли; Роли эффективно назначаются объектам домена при их создании.
  3. В-третьих, контекст вызывает метод Role для первого объекта, который принимает участие в вариант использования.
  4. С этого момента роли вызывают методы друг друга для выполнения вариант использования. Метод роли может вызывать метод на себя который фактически обрабатывается объектом, который в данный момент играет роль. Вот как роли вызывают рудиментарные операции с данными объектов, которые в данный момент их воспроизводят.

Внедрение DCI

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

Методы реализации различаются для разных языков программирования. Общим для многих подходов является то, что роли представлены такими конструкциями, как универсальные шаблоны, шаблоны, классы или черты. Код для базовой логики предметной области реализуется отдельно в соответствии с обычной объектно-ориентированной практикой и чаще всего с использованием классов. Код каждой роли вводится в объект домена, который будет воспроизводить его во время вариант использования постановление. Для реализации Роли, метод инъекции обычно требуется. Черты[2] являются одним из распространенных методов языка программирования для поддержки метод инъекции. Некоторые языки, например Scala, есть встроенная поддержка черты, а другие языки (например, Рубин и Python ) разрешить внедрение методов во время выполнения. В Ява, для поддержки DCI необходимы предварительные приемы компилятора, основанные на аннотациях.

Существует несколько примеров реализации: Болтовня -Писк,[3] C ++,[4] C #,[5] Рубин,[6] JavaScript,[7] Python,[8] Qi4J (Ява ),[9] Scala, Perl,[10] и PHP.[11] и несколько были добавлены на сайт fulloo.info, поддерживаемый создателями DCI.

История

DCI был изобретен Трюгве Реенскауг, также изобретатель MVC. Текущая формулировка DCI - это в основном работа Reenskaug и Джеймс О. Коплиен.[нужна цитата ]

DCI возникла в значительной степени как результат работы Трюгве Реенскауг по ролевому моделированию.[12] Трюгве давно осознал, что роли играют центральную роль в том, как программисты думают об объектах, и что развитие технологии языков программирования на основе классов лишило большую часть мотивации думать об объектах в программе. Это, в свою очередь, затрудняло рассуждение о программе во время выполнения. Кроме того, тот факт, что объектно-ориентированные языки программирования предлагали только классы для выражения программной логики, оставил программиста во власти структурного макета данных для определения поведения, что неестественно по сравнению с описанием поведения на границах ролей. Это, в свою очередь, затрудняло рассуждение о поведении программы, чем, скажем, в процедурной программе в Фортран.[нужна цитата ]

Трюгве чувствовал важность создания программных структур, о которых можно было бы рассуждать, и начал обобществлять эти идеи еще в 2000 году. К 2006 году у него была рабочая модель дизайна, и его открытие в 2008 году работы Шерли над Черты предоставили краеугольный камень, который обеспечил бы выражение этих идей на естественном языке программирования. Он прототипировал идеи в среде программирования Baby, написанной на Squeak. Джим Коплиен присоединился к Трюгве примерно в 2007 году, и к середине 2008 года у него был запущен прототип. C ++. Стин Леманн, Рикард Оберг и Никлас Хедман ускорили адаптацию этих идей к Рубин и Ява в течение следующего года или около того с помощью платформы Qi4j.[1] Многие дополнительные языковые адаптации последовали за сессией на конференции JaOO в Дании в сентябре 2008 года. В 2010 году язык Marvin был создан Руне Лунд-Сёлтофт. Это была первая языковая сборка с нативной поддержкой DCI. Марвин был главным образом предназначен для проверки концепции, чтобы продемонстрировать идею «без впрыска DCI». Большинство предыдущих реализаций изменяли объекты ролевого игрока таким образом, чтобы они были видны вне контекста. Джеймс Коплиен создал trygve, первую языковую сборку с нуля для поддержки DCI.

Многие ключевые достижения в области объектной ориентации за последние двадцать лет демонстрируют компоненты DCI. Хотя ни один из них полностью не предоставляет вычислительную модель DCI, перекрытие предполагает[согласно кому? ] что проблемы, которыми занимается DCI, являются давними и фундаментальными.

  • Миксины были способом инкапсулировать код для конкретной функциональности «что делает система» в закрытой форме; однако не существует последовательного механизма для связывания нескольких миксинов в единицу на уровне вариант использования. Миксины очень близки к концепции роли в DCI.[нужна цитата ]
  • Множественная отправка была ранней попыткой более полно отделить алгоритм от объектов, участвовавших в его выполнении, но в нем отсутствовало разделение DCI общих повторяющихся алгоритмов от фрагментов кода, которые можно было индивидуально локализовать для отдельных объектов. DCI концептуально ведет к более широкому повторному использованию одного алгоритма в закрытой форме для множества наборов объектов самых разнородных типов. Объект Context DCI действует как явный диспетчер интеллекта, аналогичный механизмам диспетчеризации языков с множественной диспетчеризацией.[нужна цитата ]
  • Настоящие объектно-ориентированные языки программирования, такие как Себя попытался разрушить дихотомию между областями классового программирования и объектного исполнения. Хотя это помогло программистам сосредоточиться на объектах времени выполнения, оно принесло в жертву знания на уровне кода об отношениях между ними. DCI восстанавливает эти знания в контекстах и ​​в статических отношениях между методами ролей.[нужна цитата ]
  • Внедрение зависимости - это давний подход к изменению функциональности объекта во время выполнения, позволяя ему «передавать» часть своего выполнения внешнему объекту, который может быть повторно привязан по желанию. Большинство реализаций[который? ] внедрения зависимости приводят к самостоятельная шизофрения проблема,[нужна цитата ] какие реализации DCI адресуются правильно. Такие системы, как Elmo, используют этот подход, который вносит дополнительную сложность в устранение неоднозначности методов и дублирования имен элементов данных.[13][требуется полная цитата ]
  • Мультипарадигмальный дизайн[14] попытался разделить поведение и структуру, сопоставив поведение с процедурным дизайном, а структурный компонент - с объектами, обеспечивая свободный доступ между ними, в соответствии с принципами проектирования C ++. Однако мультипарадигмальный дизайн плохо отражает взаимосвязь между процедурной и структурной частями дизайна, и в целом не может понять связность подхода DCI.[нужна цитата ]
  • Аспектно-ориентированное программирование (АОП), пожалуй, самый близкий исторический родственник DCI. Однако большая часть использования аспектов тесно связана с точкой зрения программиста, а не с ментальной моделью конечного пользователя. сценарии использования. Кроме того, без сильной инструментальной поддержки Аспекты обычно делают код менее читаемым с точки зрения понимания того, что на самом деле происходит в данный момент. Pointcut. Основное отличие состоит в том, что в DCI структура алгоритма является первичной, а его взаимодействие с кодом вне себя рассматривается как вторичное и минимальное. Кроме того, такое взаимодействие учитывает инкапсуляцию кода, с которым оно взаимодействует. В АОП Pointcut и совет несут равную важность и, хотя физически не пересекаются, должны пониматься вместе, чтобы понять код, потому что совет является агрессивным в Pointcut. В то время как АОП обеспечивает административную группировку связанного набора отдельных локальных модификаций, которые вместе пересекают первичную структуру кода, DCI является семантическим выражением алгоритма с первоклассным статусом анализа, который вызывает существующие методы объекта. DCI нельзя рассматривать как способ совет и позволяя частям вводить его в ряд регуляризованных Pointcuts.[нужна цитата ]
  • Ролевое программирование объединяет идеи из Аспектно-ориентированное программирование, концептуальное моделирование [15] и больше. Ранние попытки (1991) определяли роли независимым образом,[16] но более поздние подходы (2002 г. и последующие) сходятся во мнении, что роли зависят от контекста (также «команды» [17] или "учреждения" [18]). В ролевом программировании роли определяются относительно некоторой внутренней (или базовой) сущности, что соответствует дихотомии данных и ролей в DCI. Концепция контекста по сути одинакова в обоих подходах. Оба подхода подчеркивают взаимодействие между группой ролей.
Можно выделить несколько отличий. Ролевое программирование ориентировано на добавление поддержки ролей в объектно-ориентированное. языки программирования где упор делается на повышение выразительности языка программирования и создание большего количества дизайнов. Для сравнения, DCI уделяет больше внимания метод того, как должны отражаться ментальные модели, частично определяя этот метод как ограничения того, что следует рассматривать как юридический дизайн, соответствующий DCI. Например: авторы DCI склонны не одобрять использование наследования (например, «внутри DCI вы не наследуете роли» [19]), тогда как ролевое программирование охватывает (и даже расширяет) наследование как центральную концепцию объектно-ориентированного программирования, поддерживая свободное сочетание с другими концепциями. DCI подчеркивает, что самостоятельная шизофрения следует избегать, в то время как ролевое программирование утверждало, что управляет разделенными объектами таким образом, что шизофрения больше не является проблемой [20] но помощник для более гибких дизайнов. В более поздней статье авторов DCI утверждается, что самошизофрения остается проблемой в ролевом программировании, используя контрпример, основанный на модифицированной реализации Алгоритм Дейкстры.[21]

Рекомендации

  1. ^ а б Фреймворк Qi4j
  2. ^ Натаниэль Шерли и др. Черты: составные единицы поведения. http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf
  3. ^ Здравый смысл объектно-ориентированного программирования Трюгве Реенскауг, http://heim.ifi.uio.no/~trygver/2009/commonsense.pdf
  4. ^ Полная документация OO DCI, примеры C ++, http://fulloo.info/Examples/C++Examples/index.html
  5. ^ Исходный код C # на GitHub, https://github.com/programmersommer/DCISample
  6. ^ Исходный код Ruby в группе Google Object-Composition,https://groups.google.com/group/object-composition/browse_thread/thread/561f638b43f1b960# 17.10.2009
  7. ^ Исходный код JavaScript в группе Google Object-Composition,https://groups.google.com/group/object-composition/browse_thread/thread/8ec4cf18e127cc3e# 17.10.2009
  8. ^ https://pypi.python.org/pypi/roles
  9. ^ Исходный код Qi4j в группе Google Object-Composition,https://groups.google.com/group/object-composition/browse_thread/thread/fe317e615b9008fe# 17.10.2009
  10. ^ Релиз на CPAN: https://metacpan.org/release/DCI В архиве 2012-01-24 в Wayback Machine
  11. ^ Исходный код PHP в Google, https://code.google.com/p/php-coredci
  12. ^ Трюгве Реенскауг. Работа с объектами: метод разработки программного обеспечения OOram. Прентис-Холл, 1995.
  13. ^ Джеймс Ли, руководство пользователя Elmo, http://www.openrdf.org/doc/elmo/1.5/user-guide.html В архиве 2011-07-21 на Wayback Machine
  14. ^ Джеймс Коплиен, Мультипарадигмальный дизайн для C ++. Аддисон-Уэсли, 1998.
  15. ^ Фридрих Штайман, О представлении ролей в объектно-ориентированном и концептуальном моделировании, 2000 г., http://www.fernuni-hagen.de/ps/veroeffentlichungen/zeitschrift_46129.shtml
  16. ^ Джоэл Ричардсон и Питер Шварц, Аспекты: расширение объектов для поддержки нескольких независимых ролей, 1991, http://www.informatik.uni-trier.de/~ley/db/conf/sigmod/RichardsonS91.html В архиве 2007-10-17 на Wayback Machine
  17. ^ Стефан Херрманн, Объектные команды: улучшение модульности для сквозного сотрудничества, http://www.objectteams.org/publications/index.html#NODe02, 2002
  18. ^ Гвидо Балдони и др., Роли как координационная конструкция: знакомство с powerJava, 2005 г., http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.77.6337
  19. ^ Дж. Коплиен, автор сообщения в группе Google Object-Composition, https://groups.google.com/forum/?hl=en#!topic/object-composition/haza-J2Doz8 21.10.2010
  20. ^ Стефан Херрманн, Демистификация объекта - шизофрения, 2010, http://www.objectteams.org/publications/index.html#MASPEGHI10
  21. ^ Джеймс О. Коплиен и Трюгве Миккьель Хейердал Реенскауг, Парадигма данных, контекста и взаимодействия. В Гэри Т. Ливенс (ред.): Конференция по системам, программированию и приложениям: программное обеспечение для человечества, SPLASH '12, Тусон, Аризона, США, 21–25 октября 2012 г. ACM 2012, ISBN  978-1-4503-1563-0, стр. 227 - 228, http://dl.acm.org/citation.cfm?id=2384782&dl=ACM&coll=DL.

внешняя ссылка