RSS Записей | RSS Комментариев
Ядоблог - Stay upwind

Архив ‘Проектирование’ Категории

Правильный OOP

октября 17, 2014 | Комментариев нет

Достойное видео

Без рубрики IAD

Node.js loopback

октября 4, 2014 | Комментариев нет

Node.js loopback, как отличный инструмент для разворачивания RESTful бекендов:

Мастер-класс по подготовке RESTful API с нуля за пол часа:
источники данных, модели, связи, ACL, API explorer, сервис для AngularJS.

Без рубрики IAD

DDD

июля 18, 2013 | Комментариев нет
Без рубрики IAD

Архитектура приложений. DDD(Domain Driven Design), MongoDB, PHP, скрипты.

марта 10, 2013 | 3 Комментариев

Размышления о применимости DDD (Domain Driven Design) для веб проектов не дают покоя.
Сразу оговорюсь, что рассуждения касательно применимости не в энтерпрайз, а в своих мелких проектикиках.

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

1. принцип DDD — проектируем модель, а затем думаем как сохранять. Хорошо, если модель легко проектируется на место хранения…
Возможно у меня кривое представление модели, но, под моделью(MVC, DDD) я понимаю большой жирный слой, в котором нужно реализовать следующее:

Интерфейсы, реализация классов объектов(геттеры, сеттеры). Связи между объектами пока опустим.
Обычно не сложно.

Сохранением объектов занимаются мапперы. Проектируем интерфейс маппера и реализуем по 1 мапперу на каждый класс объекта. Что-то простое плоское сохранять и извлекать легко. Идеологически, в коллекциях MongoDB правильно хранить агрегаты. Агрегаты — это сложные объекты, имеющие не плоскую структуру(состоящие из вложенных объектов). Для декомпозиции агрегатов нужен ещё один уровень абстракции. Назовём его Data Abstraction layer(DAL). Но о нём позже.

О реализации маппера, 2 варианта:

  • Dependency Injection, инициатива создания объекта исходит от маппера. При создании объекта передаём ссылку на его маппер.
  • Изначальное наделение объектов информацией о их маппере.

Оба варианта холиварные. Мне нравится второй, т.к. мапперы меняются не так часто(никогда) и получаем автокомплит.

Опять же удобно сделать MappersManager, который будет конструировать мапперов.

IdentityMap для объектов:
Неплохо бы кешировать объекты, чтобы при повторном обращении к мапперу получать данные из кеша, 2 варианта:

  • декоратор к мапперу
  • отдельный компонент, обращение к которому маппер делает самостоятельно

Мне нравится второй, т.к. в маппере могут быть самостоятельные обращения к IdentityMap.

Lazy Load конструирование данных:
При выборке большого количества объектов, маппер возвращает итератор над коллекцией, элементы которой будут созданы только в момент фактического доступа (foreach), 2 варианта:

  • либо отключаем IdentityMap для этой коллекции
  • либо используем инвалидацию хранилища в IdentityMap(сброс кеша).

Инвалидация IdentityMap:
Для этого все создаваемые маппером объекты нужно обернуть в проксирующие дектораторы. Которые декорируют метод объекта getId(), без фактического обращения к объекту. Иногда это выручает, т.к. не всем нужно кроме Id элемента что-то ещё.
Этот проксирующий декоратор позволит создать объект, в случае, если хранилище IdentityMap было инвалидировано.

Зависимые загрузки. Проблема 1+n запросов.
$posts = $user->posts() и затем foreach $posts->comments() фактически вызовет N запросов(для каждого поста по запросу), решается уведомлением зависимого маппера о вероятном использовании некоторых объектов. Например CommentMapper::notifyUsage($comment_id) или MapersManager::getMapper(‘comment’)->notifyUsage($comment_id);
Но для этого нужно отказаться от итератора над коллекцией возвращаемых значений для постов.

Связи. Самое сложное, 2 решения:

  • Анемичная модель: PostService::addComment($post, $comment). В этом случае PostService должен выполнить операцию сам(изменить фактические данные). Для этого он должен знать о реальной структуре хранимых данных. И обращаться ему придётся к Data Abstration Layer, на уровень ниже.
  • Богатая модель: $post->addComment($comment); В этом случае, вероятно, вызов должен быть делегирован обоим мапперам, чтобы каждый выполнил свою часть операции. Хранение связей в MongoDB отличается от реляционной модели. Возможно связь должны хранить оба элемента(тип значения «список» в MongoDB).

Скрипты(отчёты, регламентные процедуры, и.т.д.):

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

 

Резюме:

Это только первый слой, без Data Abstration Layer. Выглядит уже сложно. Возникает ощущение программирования ради программирования.

Как возможная альтернатива: Анемичная модель и отказ от объектов пользу массивов. Интеграция приложения на уровне базы данных, когда всё приложение пронизано знанием о способе хранения и структуре возвращаемых данных.

Как показывает опыт анемичная модель доминирует в вебе. Суппорт анемичной модели так же более лёгкое занятие.

Без рубрики IAD

Книга выходного дня: Фриман и Фриман. Паттерны проектирования.

июня 1, 2012 | Комментариев нет

Рецензия на хабре: http://habrahabr.ru/post/144995/
Написана достаточно свежо. Книга насквозь пропитана примерами из рисунков с надписями, читать прятно и весело(порой разрывает от смеха) =)
Думаю отличная книжка для начинающих изучать паттерны. Настоятельно рекомендую.

Пример иллюстраций:

Без рубрики IAD

sphinx, xmlpipe2, PHP и MongoDB или загибаем трубу из MongoDB в сфинкс, используя PHP

мая 22, 2012 | Комментариев нет

ТЗ: организовать релевантный поиск.

ТУ: данные хранятся в MongoDB, бэкенд на PHP.
Читать полностью »

Без рубрики IAD

Абстракции

мая 10, 2012 | Комментариев нет

… дальше остается только решить проблему возросшего количества уровней абстракции. Которую мы решим введением еще одного уровня абстракции. Whait… oh, shi…

Без рубрики IAD

Проектирование ПО

марта 29, 2012 | Комментариев нет

Отличные слайды по проектированию ПО. http://www.slideshare.net/munkie/orm-8320208
Доменная модель предметной области в полный рост и все следующие из неё ништяки. Отличная работа.

Без рубрики IAD

MongoDB, когда хранить документ вложенным в другой, а когда в отдельной коллекции

февраля 12, 2012 | 1 Комментарий

Задача: хранить авторов к публикациям.
Делема: хранить авторов в отдельной коллекции или внутри документа публикации?

Решение #1:

{
  "_id" : ObjectId("4dd491695072aefc456c9aca"),
  "username" : "alphareplicant",
  "email" : "roybatty@androids.org",
  "fullname" : "Roy Batty",
  "joined_at" : ISODate("2011-05-19T03:41:29.703Z"),
  "address" : {
    "street" : "13 Tannhauser Gate",
    "city" : "Caprica",
    "state" : "CC",
    "zipcode" : 512
  },
}

Решение #2:

{
  _id : ObjectId("4dcd2abe5981aec801010000"),
  title : "The only perfect site is hind-site",
  content : "Loren ipsum dolor sit amet…",
  saved_at : ISODate('2011-05-16T18:42:57.949Z'),
  author_id : ObjectId("4dd491695072aefc456c9aca")
}

Так как же поступить?
Этот вопрос всегда возникает, при проектировании способа хранения данных. в nosql решениях.

Решение #1:
Плюсы: данные о авторе доступны в основном документе публикации, что экономит на количестве запросов в базу.
Минусы: Если документы существенно велики, и используется не курсор, а массив, для работы с данными. Можно допустить перерасход памяти.

решение #2:
Плюсы: лёгкие документы
Минусы: дополнительная коллекция, документы которой можно извлечь дополнительным запросом.

Правило:
Если документ коллекции содержит в себе вложенный документ, как часть его, и, вложенный документ не требуется как самостоятельный документ — его следует включить, согласно решению #1. Чаще всего это характеризуется связью 1-1 (Один к одному).
Если вложенный документ является самостоятельным и является вложенным в другие документы (например категория), его следует вынести в отдельную коллекцию. Связь между документами будет 1-∞(один ко многим) или ∞-∞(много ко многим).

Без рубрики IAD

Пять копеек о моём видении нормального проектирования

февраля 11, 2012 | Комментариев нет

Первый уровень — фасад, которому передаются команды(понятные пользователю. например: удали запись №10) на выполнение

Второй уровень — уровень модели предметной области(он содержит фасады и сервисы отражающие сущности предметной области. например: публикация, комментарий, страница, пользователь).

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

Без рубрики IAD
© 2010 Ядоблог. Все права защишены.
Powered by Лаборатория Яда. Написать администратору