<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5553879771699141855</id><updated>2022-11-20T01:10:12.377+02:00</updated><category term="Разработка"/><category term="BPMS"/><category term="Разное"/><category term="OpenSource"/><category term="Ruby"/><category term="Инженерия ПО"/><category term="Книги"/><category term="Управление проектами"/><category term="Инструменты"/><category term="Работа"/><category term="TODO"/><category term="ООП"/><category term="Философия"/><category term="1С"/><category term="Rails"/><category term="Цитата"/><category term="BRMS"/><category term="XML"/><category term="Управление требованиями"/><category term="SOA"/><category term="DBMS"/><category term="Провижининг"/><category term="Web 2.0"/><category term="Перевод"/><category term="Java"/><category term="Шпаргалка"/><category term="Английский"/><category term="Sandbox"/><category term="XRX"/><category term="Обучение"/><category term="ITSM"/><category term="ORM"/><title type='text'>ИТ блокнот /Николай Войнов/</title><subtitle type='html'>винегрет восприятия информационных технологий</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>493</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-5215812727965581548</id><published>2020-07-29T14:06:00.000+02:00</published><updated>2020-07-29T14:14:04.593+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="OpenSource"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Инструменты"/><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><title type='text'>Clerq Ruby Gem</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Раз в год, за пару месяцев до его конца случается у меня приступ &quot;программазма&quot; и я совершенствую свой гем с помощью которого я разарабатываю большие документы требований к ПО как аналитик.&lt;br /&gt;&lt;br /&gt;В прошлом году, пристут был навеян Clear Architecture и получился&amp;nbsp; &lt;a href=&quot;https://github.com/nvoynov/clerq&quot;&gt;Clerq&lt;/a&gt;. И так мне он понравился что даже заморочился на красивое описание в &lt;a href=&quot;https://nvoynov.github.io/clerq/&quot;&gt;github pages&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/5215812727965581548/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=5215812727965581548' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/5215812727965581548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/5215812727965581548'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2020/07/clerq-ruby-gem.html' title='Clerq Ruby Gem'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-6888012445386787221</id><published>2017-02-10T13:42:00.000+02:00</published><updated>2017-02-10T13:45:15.269+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="OpenSource"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><title type='text'>И снова Creq</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Создав несколько документов требований в &lt;a href=&quot;https://github.com/nvoynov/minireq&quot;&gt;Minireq&lt;/a&gt;, и поработав близко с гибкой командой разработки в течении 9 месяцев, пришел к выводу, что&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;зря обвесил его дополнительным DSL, т.к. потребности его использования не было.&lt;/li&gt;&lt;li&gt;вопрос с публикацией не актуален, т.к. GitLab отлично понимает Markdown.&lt;/li&gt;&lt;li&gt;вопрос с трассировкой не был востребован, соответственно до рабочего инструмента доведен не был.&lt;/li&gt;&lt;/ul&gt;Поэтому в один прекрасный момент, я решил все это из Minireq убрать. Но вместо уборки, потратил пару недель и упростив код, заменил новым инструментом &lt;a href=&quot;https://github.com/nvoynov/creq&quot;&gt;Creq&lt;/a&gt;. Фактически, это Minireq без DSL.&lt;br /&gt;&lt;br /&gt;FPA и PERT DSL были вынесены в отдельный проект &lt;a href=&quot;https://github.com/nvoynov/seecalc&quot;&gt;SeeCalc&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Дальше буду продолжать в сторону трассировки, но уже в рамках промо-проекта.&lt;br /&gt;&lt;br /&gt;Вообще, кажется что подход Minireq/Creq для управления требованиями сработал, сам использую :)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/6888012445386787221/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=6888012445386787221' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6888012445386787221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6888012445386787221'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2017/02/creq-console-requirement-managment.html' title='И снова Creq'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-2458331714251277526</id><published>2016-11-29T13:24:00.000+02:00</published><updated>2016-11-30T11:18:15.517+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DBMS"/><category scheme="http://www.blogger.com/atom/ns#" term="ORM"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>SPI, API и ORM</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Немногим более полу года работаю как владелец продукта. На примере двух относительно простых проектов SPI (Angular) плюс API (Java, Spring, Hibernate...) заметил интересную штуку - во втором проекте команда разработки сразу выбрала Hibernate, хотя и сталкивалась с проблемами и ограничениями в предыдущем проекте. Проблемы возникают в половине случаев, как только задача отходит от стандартной функциональности типа CRUD.&lt;br /&gt;&lt;br /&gt;Первым забавным примером был отчет по продажам. Пусть у нас есть плоская выборка по продажам: период, торговый автомат, номенклатура (количество всегда единица) и нужно сгруппировать продажи по дням, по неделям, по месяцам, по неделям и автомату, по неделям и номенклатуре, по номенклатуре и количеству, по автомату и номенклатуре.&lt;br /&gt;&lt;br /&gt;Подобная задача за час решается средствами SQL - имеем плоскую выборку, которую от условий группировки оборачиваем внешней группировкой, что-то типа запроса ниже. Но такого нет в Hibernate ...&lt;br /&gt;&lt;br /&gt;-- группировка &lt;br /&gt;select month(sold_at), count(id)&lt;br /&gt;from (&lt;br /&gt;&amp;nbsp; -- исходный запрос по продажам&lt;br /&gt;&amp;nbsp; select id, sold_at, machine_id, item_id, item_name&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; from sales s join items i on i.id = s.item_id)&lt;br /&gt;group by 1, 2&lt;br /&gt;order by 1 DESC&lt;br /&gt;&lt;br /&gt;Вторым примером, сейчас команда разрабатывает общий механизм для серверной фильтрации, сортировки и постраничной выдаче (есть таблица на фронте, которая умеет все это делать). Задача также прямо ложится в SQL - простое дописывание where, order by, limit, skip. Но для каждого элемента свой объектный механизм :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Как-то в целях самообразования, на примере простой мастер-детали я сделал две версии API (ruby + grape + sequel) первую просто через SQL, вторую через Sequel::Model. Для простых моделей выигрыш минимальный - можно вполне обосновано забить на модели и оставаться в известной 30 лет логике SQL. Можно рассматривать ОРМ только если много вложенных моделей или сложная объектная логика. Например, для различных отчетов ОРМ не нужен и скорее вреден.&lt;br /&gt;&lt;br /&gt;Sequel прекрасен тем что предоставляет оба подхода в одной коробке. На будущее, если возникнет задача. буду делать на SQL, и только по мере усложения переходить к моделям.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/2458331714251277526/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=2458331714251277526' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/2458331714251277526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/2458331714251277526'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2016/11/spi-api-orm.html' title='SPI, API и ORM'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-4999532222062907936</id><published>2016-06-20T11:14:00.003+02:00</published><updated>2016-06-20T11:14:46.453+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><title type='text'>Minireq 0.1.3 и Minireq-gitbook 0.1.2</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Найти время на проект все сложнее и сложнее. Но за последние пару дней удалось подчистить различные досадные недоразумения и выложить новые версии.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/nvoynov/minireq&quot;&gt;&lt;b&gt;Minireq&lt;/b&gt;&lt;/a&gt; наконец научился делать из макросов [[requirement_id]] нормальные кросс-ссылки внутри документа а также определился с каталогом ресурсов. При создании / инициализации проекта создается каталог docs/assest в который складываются изображения и другие ресурсы. В текстах требований пишу ссылки через assests/resource - локально их не видно, но после сборки docs/requirements.md все встает на свои места. Начал было преобразовывать ссылки при сборке документа, но потом бросил.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/nvoynov/minireq-gitbook&quot;&gt;&lt;b&gt;Minireq-gitbook&lt;/b&gt;&lt;/a&gt; научился делать правильные ссылки на комбинацию ASCII (requirement id) и русского текста в заголовках. Также добавлена команда deploy, которая извлекает данные из репозитория, делает книгу и разворачивает на веб-сервере.&lt;br /&gt;&lt;br /&gt;Немного побаловался с Git Hooks (это было довольно весело потанцевать на винде сразу с node js, ruby, git sh и Go) и сейчас выглядит процесс примерно так:&lt;br /&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Commit и Push в удаленный репозиторий.&lt;/li&gt;&lt;li&gt;Git Hook вытягивает данные, строит и разворачивает книгу в сети.&lt;/li&gt;&lt;/ol&gt;Если проектов несколько, каждый проект нужно разворачивать на разных port и live reload port.&lt;br /&gt;&lt;br /&gt;Сейчас собираюсь сделать АПИ для комментариев и возможно в ближайшее время появится плагин для комментирования.&lt;br /&gt;&lt;br /&gt;Когда дойдут руки постараюсь вынести PERT и FPA в отдельные плагины. Они достаточно интересны сами по себе. Спасибо Роману за &lt;a href=&quot;https://gogs.io/&quot;&gt;Gogs&lt;/a&gt; :)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/4999532222062907936/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=4999532222062907936' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/4999532222062907936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/4999532222062907936'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2016/06/minireq-013-minireq-gitbook-012.html' title='Minireq 0.1.3 и Minireq-gitbook 0.1.2'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-8134110908241020511</id><published>2016-05-21T11:56:00.001+02:00</published><updated>2016-05-21T12:15:22.233+02:00</updated><title type='text'>Minireq-Gitbook. Публикация документа требований</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Последнюю неделю&amp;nbsp; внедряю &lt;b&gt;&lt;a href=&quot;https://github.com/nvoynov/minireq&quot;&gt;Minireq&lt;/a&gt;&lt;/b&gt; в компании. Пока просто пишу требования в Markdown и публикую на своей машине требования в виде статического сайта. На следующей неделе буду заниматься вопросами развертывания для всех заинтересованных лиц и комментированием. Третий этап трассировка и все остальное.&lt;br /&gt;&lt;br /&gt;Для публикации используется &lt;a href=&quot;https://github.com/GitbookIO/gitbook&quot;&gt;GitBook&lt;/a&gt; и дополнительный &quot;plugin&quot; &lt;b&gt;&lt;a href=&quot;https://github.com/nvoynov/minireq-gitbook&quot;&gt;minireq-gitbook&lt;/a&gt;&lt;/b&gt;, который просто делает SUMMARY.md и еще какие-то мелочи. Соответственно, самый простой способ получить документ - преобразовать команды посредством gitbook pdf/epub/mobi.&lt;br /&gt;&lt;br /&gt;Думаю вынести трассировку и оценки в отдельные проекты плагинов. Появляются также мысли по task management через интеграцию с Jira.&lt;br /&gt;&lt;br /&gt;Еще один логичный ход - использование Gitbook для написания прочей документации, воде Architecture Design Document и различных руководств. &lt;br /&gt;&lt;br /&gt;В общем дело идет и самое время подумать как органично вписать проект в процессы разработки, где и как развертывать, отслеживать обновление документов и т.п.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/8134110908241020511/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=8134110908241020511' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/8134110908241020511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/8134110908241020511'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2016/05/minireq-gitbook.html' title='Minireq-Gitbook. Публикация документа требований'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-2932295204596913469</id><published>2016-05-14T11:46:00.001+02:00</published><updated>2016-05-14T11:46:38.410+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><title type='text'>Minireq Ruby Gem - requirements management</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div style=&quot;text-align: right;&quot;&gt;The Creq is dead, long live the Minireq.&lt;/div&gt;&lt;br /&gt;Встречайте &lt;b&gt;&lt;a href=&quot;https://github.com/nvoynov/minireq&quot;&gt;Minireq Ruby Gem&lt;/a&gt;&lt;/b&gt; для управления требованиями. Вся информация для старта есть в репозитории. Внутри есть &lt;a href=&quot;https://github.com/nvoynov/minireq/tree/master/lib/minireq/promo&quot;&gt;Promo проект&lt;/a&gt; с требованиями к Minireq и даже &lt;a href=&quot;https://github.com/nvoynov/minireq/blob/master/lib/minireq/promo/docs/requirements.md&quot;&gt;выходной Markdown документ&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Грубо, главной целью проекта было построить простейшую систему для управления требованиями на следующих основных принципах:&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Писать требования в любом текстовом редакторе, в в одном или нескольких файлах, в зависимости от выбранной структуры (фичеры, подсистемы, функции и т.п. Так чтобы несколько человек работающих с требованиями не мешали друг другу.&lt;/li&gt;&lt;li&gt;Хранить в Git репозитории и получать привычные инструменты хранения версий.&lt;/li&gt;&lt;li&gt;Иметь готовые инструменты трассировки и оценки усилий на разработку (PERT, FPA). &lt;/li&gt;&lt;li&gt;Иметь возможность быстрого расширения системы, исходя из потребностей конкретного проекта, команды или процесса.&lt;/li&gt;&lt;/ul&gt;Сейчас инструмент находится на стадии проверки концепции и есть уже несколько мыслей по расширению. Одна из сильнейших сторон решения - упаковка кода в Gem и расширение CLI проекта через Thor. Поэтому расширять проект уже сейчас крайне просто.&lt;br /&gt;&lt;br /&gt;Главная действительно недостающая часть сейчас - это процессы публикации и рецензирования (грубо просто комментирование). Рабочее решение - использовать для этого GitBook. Чтобы решить вопрос рецензирования, нужно будет дописать плагин.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;b&gt;PS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;В процессе ознакомления с GitBook захотелось использовать его для всего остального - для остальной документации, базы знаний по проекту&amp;nbsp; т.п. Так и просится, поскольку имеет готовый сервер, который еще отслеживает изменения в файловой системе.&lt;br /&gt;&lt;br /&gt;Дальше очень хочется показать как пользоваться трассировками. Но для начала сделаю трассировку требований к Promo на исходный код и тесты :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Пока не совсем ясно как удобно организовать работу когда проект состоит из нескольких приложений и групп разработки соответственно. &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/2932295204596913469/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=2932295204596913469' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/2932295204596913469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/2932295204596913469'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2016/05/minireq-ruby-gem-requirements-management.html' title='Minireq Ruby Gem - requirements management'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-336642073764921139</id><published>2016-04-24T19:58:00.002+02:00</published><updated>2016-04-24T22:20:10.222+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Sandbox"/><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><title type='text'>Requirements Management on Ruby 2</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Решил продолжить работу по управлению требованиями посредством консоли, текстового редактора и git.&lt;br /&gt;&lt;br /&gt;Первая попытка была прошлой осенью. И тогда появился creq и была даже попытка собрать требования для creq в &quot;системе creq&quot;. При первом же сеансе использования сразу стало понятно что писать одно требование в одном файле и буквально каждый файл перевязывать ссылкой на родителя ... не взлетит. &lt;br /&gt;&lt;br /&gt;Покрутив проблему в голове кажется нашел удачное решение - требование это просто заголовок и текст до следующего заголовка. В заголовке указывается идентификатор; сразу после заголовка может идти блок атрибутов требования.&lt;br /&gt;&lt;br /&gt;Таким образом все встает на свои места - все что относится к некоторой функциональности (feature) можно записать в одном файле и при этом не терять структуру требований и необходимый уровень точности.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Пример будет дальше, а пока в процессе первой упрощенной реинкарнации creq без лишней нагрузки типа документов, плюс консоль irb с подключенным гемом чтобы можно было делать с репозиторием что угодно. &lt;br /&gt;&lt;br /&gt;Contents file: &lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;# [func] Functional requirements&lt;br /&gt;## [f.core] Core&lt;br /&gt;## [f.ent] Entities&lt;br /&gt;## [f.cmd] Commands&lt;br /&gt;# [intf] Interfaces &lt;br /&gt;# [nonf] Non-functional requirement&lt;/blockquote&gt;Requirement file:&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;# [f.ent.requirement] &#39;Requirement&#39; entity&lt;br /&gt;///&lt;br /&gt;parent: f.ent &lt;br /&gt;///&lt;br /&gt;System shall have &#39;Requirement&#39; entity....&lt;br /&gt;&lt;br /&gt;## [f.ent.requirement.data] &#39;Requirement&#39; data&lt;br /&gt;System shall ...&lt;br /&gt;&lt;br /&gt;## [f.ent.requirement.actions] &#39;Requirement&#39; actions&lt;br /&gt;System shall ... &lt;/blockquote&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/336642073764921139/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=336642073764921139' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/336642073764921139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/336642073764921139'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2016/04/requirements-management-on-ruby-2.html' title='Requirements Management on Ruby 2'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-144957045556874355</id><published>2016-04-19T00:17:00.005+02:00</published><updated>2016-04-19T00:20:25.142+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Sandbox"/><title type='text'>EnParser Ruby Gem. Сегментация и извлечение словоформ</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;В результате затянувшегося языкового страдания появился &lt;b&gt;&lt;a href=&quot;https://github.com/nvoynov/enparser&quot;&gt;EnParser&lt;/a&gt;&lt;/b&gt; v0.1.0. Название конечно странное, но ничего более путного в голову пока не пришло. Может parsen?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Умеет &lt;b&gt;сегментировать (разбирать на предложения) английский текст&lt;/b&gt;. При этом собирает его из plain text и позволят задать шаблоны регулярных выражений для пропуска лишних строк. Т.е. решает предыдущий вопрос с удалением тайминга из субтитров. Здесь вроде все просто, подробности в Readme.&lt;br /&gt;&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;lemma (linguistics) the basic form of a word, for example the singular  form of a noun or the infinitive form of a verb, as it is shown at the  beginning of a dictionary entry &lt;/blockquote&gt;Еще умеет &lt;b&gt;разбирать английский текст на слова, словарные формы и формы слов&lt;/b&gt;. И конечно же считает частоту. Позволят задать набор файлов со словами, которые будет пропускать. По умолчанию добавлены предлоги, местоимения и базовые глаголы.&lt;br /&gt;&lt;br /&gt;Cначала баловался на субтитрах и предполагал использовать на мелких файлах. Но вот сейчас скормил ему 570 страниц &quot;Agile Software Requirement&quot; Dean Leffingwell (предварительно перевел из pdf в plaintext через &lt;b&gt;&lt;a href=&quot;http://www.foolabs.com/xpdf/download.html&quot;&gt;xpdf&lt;/a&gt;&lt;/b&gt;). В течении минуты получил 5736 (однако дофига!) уникальных словоформ. Вот фрагмент для примера:&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;user 763 (users)&lt;br /&gt;test 767 (testing, tested, tests)&lt;br /&gt;feature 779 (features)&lt;br /&gt;requirement 858 (requirements)&lt;br /&gt;release 877 (releases, released, releasing)&lt;br /&gt;agile 1032&lt;br /&gt;system 1072 (systems)&lt;br /&gt;story 1092 (stories)&lt;br /&gt;product 1162 (products)&lt;br /&gt;team 1914 (teams)&lt;/blockquote&gt;&amp;nbsp;Получение словарной формы стало возможно благодаря &lt;a href=&quot;https://wordnet.princeton.edu/&quot;&gt;WordNet&lt;/a&gt; и магическому появлению товарища на моей кухне в нужное время.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/144957045556874355/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=144957045556874355' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/144957045556874355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/144957045556874355'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2016/04/enparser-ruby-gem-segmentation-and-words.html' title='EnParser Ruby Gem. Сегментация и извлечение словоформ'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-1930286046386196930</id><published>2015-09-26T16:45:00.000+02:00</published><updated>2015-09-26T16:45:27.008+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="OpenSource"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><title type='text'>creq ruby gem</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&amp;nbsp;И все-таки я его выпустил, пока первая и, конечно же, сырая версия ruby gem с именем &lt;b&gt;&lt;a href=&quot;https://github.com/nvoynov/creq&quot;&gt;creq&lt;/a&gt;&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-_Omfmx2Rktk/VgauQ63xNaI/AAAAAAAATSQ/UrB1KAssOYg/s1600/creq.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;196&quot; src=&quot;http://4.bp.blogspot.com/-_Omfmx2Rktk/VgauQ63xNaI/AAAAAAAATSQ/UrB1KAssOYg/s400/creq.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Creq&lt;/b&gt; это интерфейс командной строки для управления требованиями (console for requirements).&lt;br /&gt;&lt;br /&gt;На данный момент &lt;b&gt;Creq умеет&lt;/b&gt;: &lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;создавать структуру заголовков документа и структуру требований (подставляет шаблон EARS в тело требования);&lt;/li&gt;&lt;li&gt;генерировать различные полезные таблицы Приоритет-Риск-Усилия, PERT, FPA;&lt;/li&gt;&lt;li&gt;считать оценки для PERT и FPA таблиц (заполняется сгенерированная таблица руками);&lt;/li&gt;&lt;li&gt;генерировать выходной документ SRS в формате Markdown;&lt;/li&gt;&lt;li&gt;создавать структуру документа на основе шаблона Markdown, включены два шаблона IEEE-830-1998 и другой, кажется похожий на RUP.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Предполагается следующий поток работы&lt;/b&gt;:&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;аналитик создает требования через консоль, либо просто в файловой системе;&lt;/li&gt;&lt;li&gt;по мере продвижения работы с документом и синхронизации работы с другими участниками, пользователь обновляет git или другой SCM репозиторий.&lt;/li&gt;&lt;li&gt;в процессе работы, формируется документ; производятся различные оценки.&lt;/li&gt;&lt;li&gt;&amp;nbsp;... здесь где-то должно быть согласование&amp;nbsp; документа.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Что дальше?&lt;/b&gt;&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;думаю над добавлением других полезных атрибутов для требований;&amp;nbsp; &lt;/li&gt;&lt;li&gt;думаю над простеньким веб-приложением для согласования требований, в простейшем варианте только возможность комментирования, и возможно установки статусов. &lt;/li&gt;&lt;li&gt;думаю над добавлением Epic\UserStory, UseCase, TestCase и трассировкой;&lt;/li&gt;&lt;li&gt;думаю над трассировкой на элементы дизайна модуль, класс функция ... (реализованное в конкретном элементе кода и покрытое тестами требование, привет Николай :))&lt;/li&gt;&lt;li&gt;думаю над визуализацией трассировок через GraphViz (требование и все что с ним связано в цифрах)&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;ЗЫ&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;И чтобы дальше повеселить читателя, начинаю писать SRS на систему Creq в системе Creq :)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/1930286046386196930/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=1930286046386196930' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/1930286046386196930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/1930286046386196930'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/09/creq-ruby-gem.html' title='creq ruby gem'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-_Omfmx2Rktk/VgauQ63xNaI/AAAAAAAATSQ/UrB1KAssOYg/s72-c/creq.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-6900772382184699361</id><published>2015-08-21T15:37:00.002+02:00</published><updated>2015-08-21T15:37:43.757+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DBMS"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><title type='text'>Истрия одного импорта объектных данных в СУБД</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Последние несколько недель занимался оптимизацией legacy кода импорта сложной структуры объектов в БД Oracle. Первоначально ставка была сделана на оптимизацию взаимодействия с RDBMS из JDBC за счет использования PrepareStatement.executeBatch(). Эффект получился довольно заметный, но не столь значительный как ожидалось. 30 минут, которые занимала операция на предыдущей версии кода удалось превратить в 20, и конечно 33% это уже кое что... НО&lt;br /&gt;&lt;br /&gt;В общем получилось около 500 LOC лесов из различных вспомогательных классов для автоматизации работы с СУБД и пачками операторов, и около 2000 LOC основного кода импорта. Обнаружилось что большая часть конфигурации уже была оптимизирована под пачки. Также был обнаружен явно ошибочный фрагмент кода, который делал миллионы лишних обходов древовидной структуры. Но последний момент победить не удалось из-за нехватки времени и того простого факта, что другой legacy код загружал эту структуру и к нему я не прикасался. Поэтому мерилом успеха, или тестом, упрощенно считался тот факт, что таблицы СУБД после заливки legacy и новым кодом идентичны.&lt;br /&gt;&lt;br /&gt;В течении работы были явно видны ошибки при проектировании схемы СУБД (около года назад я здесь что-то писал про хранение сложных деревьев), что приводило к значительному росту количества записей в БД для каждого уникального объекта. Грубо дублирование идентификатора и типа в двух разных таблицах, плюс отдельные таблицы для иерархических связей. И разобраться  до конца во всех хитросплетениях этого Г так и не удалось. Два с половиной миллиона объектов все-таки это не шутка ... Oracle вполне себе их потребляет где-то за 10 минут.&lt;br /&gt;&lt;br /&gt;Были выходные, и этот вопрос не давал мне покоя. Больше года назад я решил, что наиболее правильным походом будет просто сериализовать часть кофигурации и решил проверить подход на реальных данных.&lt;br /&gt;&lt;br /&gt;В качестве сериализатора конечно же бы выбран Yaml и работа началась... И вот, после 18 часов работы я получил следующие результаты.&lt;br /&gt;- 2500000 записей превратились в 80000 (~3% :))&lt;br /&gt;- 10 минут непосредственно записи превратились в 1&lt;br /&gt;- загрузка также около 1й минуты.&lt;br /&gt;&lt;br /&gt;It works! И на будущее проектируйте БД более внимательно.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/6900772382184699361/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=6900772382184699361' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6900772382184699361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6900772382184699361'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/08/import-of-large-objects-to-dbms.html' title='Истрия одного импорта объектных данных в СУБД'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-1471442688184407579</id><published>2015-08-09T22:23:00.002+02:00</published><updated>2015-08-09T22:23:26.602+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>Считаем количество вызовов метда через StatckTrace</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Тот неловкий момент, когда присказка длиннее чем сказка. Поэтому сначала сказка, а если кому интересно, ниже присказка :)&lt;br /&gt;&lt;br /&gt;В итоге родился класс&lt;b&gt; &lt;a href=&quot;https://gist.github.com/nvoynov/2019e84df0de353c7d9f&quot;&gt;CallCounter&lt;/a&gt;&lt;/b&gt;, который помогает считать количество вызовов функций. В моем случае было полезно для visit-методов шаблона Visitor. Как пользоваться смотрите javadoc. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Присказка&amp;nbsp;&lt;/b&gt;&lt;br /&gt;Две недели упорно упаковывал кусок адского унаследованного кода сохранения конфигурации объектов в RDBMS в вызовы batchExec(). Упаковал и получил в итоге порядка 2500000 вставок объектов через 40 уникальных insert into в БД.&lt;br /&gt;&lt;br /&gt;Местами в существующем коде уже использовались batch-вставки, только это было совсем не очевидно в каких местах, плюс оригинальный код кроме вставки еще и занимался обновлением. Сократил время вставки где-то на 35%, хотя, признаюсь, ожидал большего :)&lt;br /&gt;&lt;br /&gt;Ну и так нормальный результат, т.к. эти 35% в абсолютных цифрах на моем железе давали 17 минут вместо 25... Добавил ведение журнала и стал смотреть более внимательно. Обход одной из основных самых сложных (и специально запутанных .. и вообще весь Domain layer сборник анти шаблонов проектирования) деревянных структур занимает 9.5 минут ...&lt;br /&gt;&lt;br /&gt;Начал ходить кругами вокруг, считать, обходить структуру и так и сяк ... потом вспомнил, что здесь нужен классический Visitor. Сделал первую попытку и решил посчитать объекты. И тут как раз и появилась тема этого поста :) А полных обход проблемной структуры занял ах 11 секунд... конечно там еще добавится реальной работы и думаю с минуту потребуется. Но так чтобы как сейчас 9.5, это же сколько помощников было!?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PS.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Классная штука этот стекТрейс, чем хуже код - тем он полезней :)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/1471442688184407579/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=1471442688184407579' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/1471442688184407579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/1471442688184407579'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/08/calc-method-call-througs-statcktrace.html' title='Считаем количество вызовов метда через StatckTrace'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-7918156403954026465</id><published>2015-05-10T11:24:00.001+02:00</published><updated>2015-05-10T11:24:12.772+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Инструменты"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>AspectJ in Action</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Читаю понемногу в свободное время &lt;a href=&quot;http://www.manning.com/laddad2/&quot;&gt;AspectJ in Action, 2th, 2009&lt;/a&gt;. Полный восторг и всем рекомендую ознакомится кто так или иначе связан с программированием. &lt;b&gt;&lt;a href=&quot;https://eclipse.org/aspectj/&quot;&gt;AspectJ&lt;/a&gt;&lt;/b&gt;, однозначно великий проект.&lt;br /&gt;&lt;br /&gt;Как раньше уже рассказывал, это была задача ведения журнала событий в унаследованном большом пользовательском приложении. Сам поступил как &quot;настоящим инженер&quot; и сделал все наоборот - сначала решил задачу, теперь читаю книгу. Всем же остальным рекомендую сначала прочесть книгу, хотя бы базовые несколько глав по Pointcut и Advice. Это широченные возможности, которые сразу не видны по интернет заметкам. Или просто практические задачи, например, прекрасный простой пример с подмешиванием интерфейса в Java сразу с готовой реализацией (аспект с реализацией прямо в файле интерфейса).&lt;br /&gt;&lt;br /&gt;На закуску несколько общих кусков из решенной задачи.&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://gist.github.com/nvoynov/b2a67304f408c2c8e607&quot;&gt;JComponentAspect.aj&lt;/a&gt; - отслеживаем создание &quot;интересных&quot; компонент и вешаем им слушателей событий, которые пишут в журнал.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://gist.github.com/nvoynov/c225b0e95807444754f3&quot;&gt;JFileChooserAspect.aj&lt;/a&gt; - вызовы диалогов выбора файлов. &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://gist.github.com/nvoynov/6ec09e1e520970d9d142&quot;&gt;JOptionPaneAspect.aj&lt;span class=&quot;creator&quot;&gt;&lt;strong class=&quot;css-truncate-target&quot;&gt;&amp;nbsp; &lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;creator&quot;&gt;&lt;strong class=&quot;css-truncate-target&quot;&gt;- &lt;/strong&gt;&lt;span class=&quot;css-truncate-target&quot;&gt;вызовы JOptionPane&lt;/span&gt;&lt;strong class=&quot;css-truncate-target&quot;&gt;, &lt;/strong&gt;&lt;span class=&quot;css-truncate-target&quot;&gt;немного сложнее т.к. много перегруженных методов.&lt;/span&gt;&lt;span class=&quot;css-truncate-target&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;creator&quot;&gt;&lt;strong class=&quot;css-truncate-target&quot;&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Конечно, хотелось бы увидеть подобную поддержку crosscutting сразу в ЯП.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/7918156403954026465/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=7918156403954026465' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/7918156403954026465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/7918156403954026465'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/05/aspectj-in-action.html' title='AspectJ in Action'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-3094338023189077108</id><published>2015-03-28T18:39:00.004+02:00</published><updated>2015-03-28T18:42:07.669+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Инструменты"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>Polyglot для Maven и конфигурация на Ruby</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Продолжаю осваивать сборку проектов на Java. Как уже писал в прошлом посте - добавляю журнал действий в интерфейсе пользователя при помощи аспектов. Рабочий Java код был написан достаточно быстро, но с интеграцией в существующий проект до сих пор не разобрался. Проект большой, тяжелый, прядка 20 отдельных модулей с компонентами. Каждый модуль в своем проекте, вся система собирается при помощи Maven. Первая реакция на Maven - полнейшая XML аллергия. По началу начал даже смотреть в сторону Gradle, но так просто от Maven&amp;nbsp; для текущего проекта все равно не избавится, и сейчас засел за чтение&amp;nbsp; &lt;a href=&quot;http://books.sonatype.com/mvnex-book/reference/index.html&quot;&gt;книжки&lt;/a&gt; и постепенно проникаюсь всей глубиной глубин :)&lt;br /&gt;&lt;br /&gt;Сегодня искал что-нибудь чтобы избавится от&amp;nbsp; конфигурации XML и попал куда надо - &lt;b&gt;&lt;a href=&quot;https://github.com/takari/maven-polyglot&quot;&gt;Maven Polyglot&lt;/a&gt;&lt;/b&gt; - теперь будем писать на привычном Ruby DSL :) Примеры можно посмотреть в свеженькой &lt;a href=&quot;http://takari.io/2015/01/28/ruby-dsl.html&quot;&gt;статье&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Итого, чтобы зажить новой понятной жизнью на новой платформе (смешно звучит) нужно прочесть книжку по Maven и поставить Полиглот :)&lt;br /&gt;Нужен JDK7+, Maven 3.3.1+ и&amp;nbsp; .mvn/extensions.xml&lt;br /&gt;&lt;div class=&quot;comment-content&quot;&gt;&lt;div class=&quot;edit-comment-hide&quot;&gt;&lt;div class=&quot;comment-body markdown-body markdown-format js-comment-body&quot;&gt;&lt;div class=&quot;highlight highlight-xml&quot;&gt;&lt;pre&gt;&amp;lt;?&lt;span class=&quot;pl-ent&quot;&gt;xml&lt;/span&gt;&lt;span class=&quot;pl-e&quot;&gt; version&lt;/span&gt;=&lt;span class=&quot;pl-s&quot;&gt;&lt;span class=&quot;pl-pds&quot;&gt;&quot;&lt;/span&gt;1.0&lt;span class=&quot;pl-pds&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pl-e&quot;&gt; encoding&lt;/span&gt;=&lt;span class=&quot;pl-s&quot;&gt;&lt;span class=&quot;pl-pds&quot;&gt;&quot;&lt;/span&gt;UTF-8&lt;span class=&quot;pl-pds&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;?&amp;gt;&lt;br /&gt;&amp;lt;&lt;span class=&quot;pl-ent&quot;&gt;extensions&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;span class=&quot;pl-ent&quot;&gt;extension&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class=&quot;pl-ent&quot;&gt;groupId&lt;/span&gt;&amp;gt;io.takari.polyglot&amp;lt;/&lt;span class=&quot;pl-ent&quot;&gt;groupId&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class=&quot;pl-ent&quot;&gt;artifactId&lt;/span&gt;&amp;gt;polyglot-ruby&amp;lt;/&lt;span class=&quot;pl-ent&quot;&gt;artifactId&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;span class=&quot;pl-ent&quot;&gt;version&lt;/span&gt;&amp;gt;0.1.7&amp;lt;/&lt;span class=&quot;pl-ent&quot;&gt;version&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;/&lt;span class=&quot;pl-ent&quot;&gt;extension&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;span class=&quot;pl-ent&quot;&gt;extensions&lt;/span&gt;&amp;gt;&lt;/pre&gt;Никакого Ruby ставить не нужно.&lt;/div&gt;О трансляции существующих pom.xml в pom.rb смотрим &lt;a href=&quot;http://takari.io/2015/03/21/polyglot-maven.html&quot;&gt;здесь&lt;/a&gt;.&lt;/div&gt;&lt;div class=&quot;comment-body markdown-body markdown-format js-comment-body&quot;&gt;&lt;/div&gt;&lt;div class=&quot;comment-body markdown-body markdown-format js-comment-body&quot;&gt;&lt;/div&gt;&lt;div class=&quot;comment-body markdown-body markdown-format js-comment-body&quot;&gt;&lt;/div&gt;&lt;div class=&quot;comment-body markdown-body markdown-format js-comment-body&quot;&gt;&lt;/div&gt;&lt;div class=&quot;comment-body markdown-body markdown-format js-comment-body&quot;&gt;По стилю описания конфигурации можно посмотреть три различных стиля одинаковой конфигурации &lt;a href=&quot;https://github.com/torquebox/maven-tools/tree/master/spec/pom_maven_style&quot;&gt;здесь&lt;/a&gt;, &lt;a href=&quot;https://github.com/torquebox/maven-tools/tree/master/spec/pom_maven_hash_style&quot;&gt;здесь&lt;/a&gt; и &lt;a href=&quot;https://github.com/torquebox/maven-tools/tree/master/spec/pom_maven_alternative_style&quot;&gt;здесь&lt;/a&gt;.&lt;br /&gt;XML ФТОПКУ! &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/3094338023189077108/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=3094338023189077108' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/3094338023189077108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/3094338023189077108'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/03/polyglot-maven-ruby.html' title='Polyglot для Maven и конфигурация на Ruby'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-6135756801089801439</id><published>2015-03-20T20:17:00.002+02:00</published><updated>2015-03-20T21:11:42.812+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Инструменты"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>Ruby 2.X TracePoint</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Когда осенью было время и я баловался с Ruby, после программирования бизнес-логики я собирался наконец попробовать AOP и дальше заняться многопоточностью и DRuby. Тогда я выбрал Aquarium и он у меня не взлетел на 1.9.3. Как обычно время кончилось, приоритеты изменились и эксперименты были отложены на неопределенное время.&lt;br /&gt;&lt;br /&gt;В последний приход программазма я баловался с Gtk3 и поставил Ruby 2.1.5. И вспомнил про AOP ... погуглил-погуглил и понял что особо ничего нового кроме &lt;b&gt;&lt;a href=&quot;http://ruby-doc.org/core-2.1.1/TracePoint.html&quot;&gt;TracePoint&lt;/a&gt;&lt;/b&gt; на ниве AOP в Ruby за пол-года не случилось. Но это кажется как раз то что нужно.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;b&gt;ЗЫ&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Что удивительно, случился такой расклад, что в настоящее время стал я ненадолго программистом. И первой же задачей  свалился мне АОП (пол-года назад писал к ней ТЗ и до сих пор не сделали ... а последний комментарий разработчика боюсь и приводить). ПО на Java, которую последний раз видел месяца три в 2007м :). Нужен журнал работы пользователя в Swing GUI. Конечно сразу я требовал там АОП :) &lt;br /&gt;&lt;br /&gt;Пока основной мой затык с Java - упаковка, с аспектом разбирался аж один день ... как же там все долго и сложно, удивительно как люди столько терпят это XML конфигурирование типа Maven :) Воистину, как сам Ruby так и его экосистема просто зовет к программированию ... но Java нет :) &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/6135756801089801439/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=6135756801089801439' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6135756801089801439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6135756801089801439'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/03/ruby-2x-tracepoint.html' title='Ruby 2.X TracePoint'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-3661708341951075538</id><published>2015-03-14T23:18:00.000+02:00</published><updated>2015-03-15T23:14:55.370+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="TODO"/><category scheme="http://www.blogger.com/atom/ns#" term="Инструменты"/><title type='text'>Requirements management console</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div style=&quot;text-align: right;&quot;&gt;&quot;Все украдено до нас&quot; (с) Unknown&lt;/div&gt;&lt;div style=&quot;text-align: right;&quot;&gt;http://www.flonatel.de/projekte/rmtoo/&lt;br /&gt;http://doorstop.info/&lt;br /&gt;https://github.com/jacebrowning/doorstop &lt;/div&gt;&lt;br /&gt;Что-то после более плотного знакомства с Ruby, его консольными инструментами, использования текстового редактора в качестве IDE вообще потянуло на консольки. Вот совсем недавно на этой неделе баловался с Gtk3 и вроде довольно быстро и красиво получается ... но тянет на консольки и текстовый редактор.&lt;br /&gt;&lt;br /&gt;В общем исследуется идея организовать управление требованиями прямо при помощи Ruby, Git, текстового редактора и файловой системы :) Что-то по аналогии с существующими системами для ведения простейших блогов на основе статического сайта.&lt;br /&gt;&lt;br /&gt;Что-нибудь типа&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;отдельных папок и шаблонов для каждого типа артефактов (требования, исходный код, тесты, запросы на изменение, etc) плюс коммиты Git ...&lt;/li&gt;&lt;li&gt;обеспечения трассировки между артефактами и их элементами; &lt;/li&gt;&lt;li&gt;набор различных скриптов для сборки документов, отчетов...&lt;/li&gt;&lt;/ul&gt;Эх достану завтра Вигерса посмотрю по инструментам ...&lt;br /&gt;&lt;br /&gt;Кто не в курсе трассировка зачем, &lt;a href=&quot;https://ashamray.wordpress.com/2010/04/20/vsts2010_rm_trace/&quot;&gt;можно почитать про реализацию в TFS&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ЗЫ&lt;br /&gt;&lt;br /&gt;И возможно даже инструмент попроще, с трассировкой только в формате&lt;br /&gt;Требование -&amp;gt; Исходный код&lt;br /&gt;Требование -&amp;gt; Тест кейс&lt;br /&gt;Запрос на изменение -&amp;gt; касается изменения Требований -&amp;gt; Исходный код + Тест кейсы.&lt;br /&gt;Запрос на изменение -&amp;gt; коммит в SCM -&amp;gt; список файлов и изменений в них &lt;br /&gt;&lt;br /&gt;В общем как ни крути - главное требование. Если для остальных артефактов существуют ссылки на требования, то можно разобрать артефакты и по ссылкам построить трассировку.&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;/ul&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/3661708341951075538/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=3661708341951075538' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/3661708341951075538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/3661708341951075538'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/03/requirements-management-console.html' title='Requirements management console'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-8240394344142234419</id><published>2015-03-13T01:15:00.001+02:00</published><updated>2015-03-13T01:23:05.707+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>Ruby contracts gem</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div style=&quot;text-align: right;&quot;&gt;А вот за что я люблю ковбоя&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;text-align: right;&quot;&gt;За то что все есть у него&lt;/div&gt;&lt;div style=&quot;text-align: right;&quot;&gt;(C) х\ф ... &lt;/div&gt;&lt;br /&gt;Информация по Ruby появляется у меня хаотически, и иногда попадаются вещи которыми просто нельзя не поделится. И вот сегодня по наводке через &lt;a href=&quot;http://rubyweekly.com/&quot;&gt;Ruby weekly&lt;/a&gt; я увидел очередной очень полезный гем &lt;a href=&quot;https://github.com/egonSchiele/contracts.ruby&quot;&gt;contracts&lt;/a&gt;. Гем который добавляет вам возможности проектирования по контракту, или как пишет автор &quot;assert на стероидах&quot;. Собственно рассказывать тут нечего - лучше один раз почитаь в сети о &quot;Design by contract&quot; и &lt;a href=&quot;http://egonschiele.github.io/contracts.ruby/&quot;&gt;посмотреть прекрасную презентацию конкретно по этому гему&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Как я уже ранее предполагал, возможно подобные вещи более актуальны для динамических интепретируемых языков - &lt;strike&gt;венгерская отладка&lt;/strike&gt; статическая проверка типов во время компиляции не работает т.к. нету компиляции :)&lt;br /&gt;&lt;br /&gt;Как-то я баловался еще с одним похожим по смыслу гемом expectations, который позволил уменьшить размер кода процентов эдак на 10 и тестов. Вот &lt;a href=&quot;http://nvoynov.blogspot.com/2014/09/ruby-defensive-programming.html&quot;&gt;здесь посмотрите первый абзац&lt;/a&gt;, если интересно.&lt;br /&gt;&lt;br /&gt;И действительно, хорошо бы добавить поддержку этого гема в YARD ... &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/8240394344142234419/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=8240394344142234419' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/8240394344142234419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/8240394344142234419'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/03/ruby-contracts-gem.html' title='Ruby contracts gem'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-825629121783425769</id><published>2015-02-09T10:20:00.002+02:00</published><updated>2015-03-16T15:16:34.889+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>Ruby DSL Handbook</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;a href=&quot;http://clean-ruby.com/dsl&quot;&gt;Курс по Ruby DSL&lt;/a&gt;, от автора Ruby DSL Handbook. Очень полезная и мощная техника. Уже успел немного побаловаться и понравилось. Считал функциональные точки, объявлял сложные свойства классов и делал классы для быстрого и удобочитаемого конфигурирования объектов в ISPS.&lt;br /&gt;&lt;br /&gt;А вот и первый красивый пример использования - метод класса.&lt;br /&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/nvoynov/8187bcea3de861a494e6.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;br /&gt;А вот и второй пример - переноса в модуль&lt;br /&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/nvoynov/66b0b8c283cda6b1335a.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/825629121783425769/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=825629121783425769' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/825629121783425769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/825629121783425769'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2015/02/ruby-dsl-handbook.html' title='Ruby DSL Handbook'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-3107164865231962257</id><published>2014-11-25T14:30:00.002+02:00</published><updated>2014-11-25T14:30:54.326+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Инженерия ПО"/><category scheme="http://www.blogger.com/atom/ns#" term="Инструменты"/><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><title type='text'>Много материалов для бизнес-аналитика</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Подходит к концу К.Вигерс. Радует очень полезными ссылками&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.seilevel.com/ba-resources/wps-and-how-to-guides/&quot;&gt;Seilevel Business Analysis White Papers&lt;/a&gt; - большое количество различных материалов с лучшими практиками; инструменты оценки затрат на работу с требованиями; сводная таблица ПО управления требованиями и их оценка.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.incose.org/ProductsPubs/products/sehandbook.aspx&quot;&gt;INCOSE SE Handbook&lt;/a&gt; -&amp;nbsp; книжка по инженерии ПО на 400 страниц - просто посмотрите &lt;a href=&quot;http://www.incose.org/ProductsPubs/Doc/SE_Handbookv3_2_2_2011_TOC.pdf&quot;&gt;содержание&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Также можно покопаться на &lt;a href=&quot;http://www.volere.co.uk/resources.htm&quot;&gt;Volere&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/3107164865231962257/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=3107164865231962257' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/3107164865231962257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/3107164865231962257'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/11/blog-post.html' title='Много материалов для бизнес-аналитика'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-7111405929916918158</id><published>2014-11-19T21:21:00.000+02:00</published><updated>2014-11-19T23:45:42.903+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Rails"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Инструменты"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>CloudIDE и Bitbucked</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Решил Харта полистать, и вот в третьей версии учебника предлагается работать в облаке - &lt;b&gt;&lt;a href=&quot;https://c9.io/&quot;&gt;CloudIDE&lt;/a&gt;&lt;/b&gt;! Все-таки в чем-то новаторский учебник :)&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-VltB5MYmrxU/VGztgElZWGI/AAAAAAAAS9Q/hu0qS71qiTo/s1600/CloudIDE.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-VltB5MYmrxU/VGztgElZWGI/AAAAAAAAS9Q/hu0qS71qiTo/s1600/CloudIDE.png&quot; height=&quot;283&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;И вторая находка &lt;b&gt;&lt;a href=&quot;https://bitbucket.org/&quot;&gt;Bitbucket&lt;/a&gt;&lt;/b&gt; - unlimited private code repositories&lt;br /&gt;&lt;ul class=&quot;feature-list&quot;&gt;&lt;li&gt;Free for 5 users&lt;/li&gt;&lt;li&gt;Git or Mercurial&lt;/li&gt;&lt;li&gt;Lightweight code review&lt;/li&gt;&lt;li&gt;Mac and Windows client&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/7111405929916918158/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=7111405929916918158' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/7111405929916918158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/7111405929916918158'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/11/cloudide.html' title='CloudIDE и Bitbucked'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-VltB5MYmrxU/VGztgElZWGI/AAAAAAAAS9Q/hu0qS71qiTo/s72-c/CloudIDE.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-4317379935489062012</id><published>2014-10-20T11:56:00.002+02:00</published><updated>2014-10-20T11:59:52.509+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><category scheme="http://www.blogger.com/atom/ns#" term="Шпаргалка"/><title type='text'>Easy Approach to Requirements Syntax (EARS), от Alistair Mavin </title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div class=&quot;tr_bq&quot;&gt;Две презентации, на которые приводил ссылки в &lt;a href=&quot;http://nvoynov.blogspot.com/2014/10/system-shall.html&quot;&gt;предыдущем посте&lt;/a&gt;,  оказались довольно интересными. Так что дальше хочется расширить  шпаргалку по синтаксису описания требований на основе этих презентаций.  Сразу нужно сказать, что автор на момент написания презентации работал в  Ролс-Ройс, поэтому есть небольшой уклон в требования к физическим  продуктам, что видно на примерах которые он включил в презентацию.&lt;br /&gt;&lt;br /&gt;Итак, &lt;a href=&quot;http://starstoroad.com/blog/wp-content/uploads/2012/11/A_Mavin_RE10_EARS_Tutorial_slides_FINAL.pdf&quot;&gt;Easy Approach to Requirements Syntax (EARS)&lt;/a&gt;,  предлагает простой синтаксис для спецификации требований на  естественном языке. Это только о формулировке требований на естественном языке. Не затрагиваются другие полезные инструменты как деревья и таблицы решений, взаимосвязь между сложными требованиями...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Мотивация&lt;/b&gt;: Высокоуровневые требования  к системе обычно формулируются на естественном языке. Пишут их люди,  которые не являются экспертами в требованиях. Свободные формулировки на  естественном языке могут вызывать различные проблемы интерпретации  текста и как следствия качества требований. И автор предлагает простое  руководство, которое поможет писать более качественные требования&lt;br /&gt;&lt;br /&gt;Все &lt;b&gt;требования можно разделить на два больших класса&lt;/b&gt; - &lt;u&gt;нормальное поведение&lt;/u&gt; (normal operation) и &lt;u&gt;нежелательное поведение&lt;/u&gt; (unwanted behaviour). Все требования на естественном языке можно  сформулировать при помощи пяти простых шаблона - 4 шаблона для  нормального поведения и 1 для нежелательного.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Нормальное поведение&lt;/b&gt; - это когда все взаимодействующие системы ведут себя как ожидается и соответствуют целям пользователя. &lt;b&gt;Нежелательное поведение&lt;/b&gt; - это любые отклонения от нормального поведения.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;# Общий шаблон &lt;/b&gt;&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;b&gt;&lt;i&gt;&amp;lt;optional preconditions&amp;gt; &amp;lt;optional trigger&amp;gt; the &amp;lt;system name&amp;gt; shall &amp;lt;system response&amp;gt;&lt;/i&gt; &lt;/b&gt;&lt;/blockquote&gt;&lt;b&gt;# Безусловное поведение - &lt;/b&gt;определяет поведение системы которое должно работать все время. Нет никаких предварительных условий или триггеров.&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;i&gt;&lt;b&gt;The &amp;lt;system name&amp;gt; shall &amp;lt;system response&amp;gt;&lt;/b&gt;&lt;/i&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Car. The car shall have a maximum retail sale price of XXX&lt;br /&gt;Car. The car shall be compliant with the safety requirements defined in XXX&lt;br /&gt;Laptop.The laptop shall have a mass of no more than XXX grams&lt;br /&gt;Laptop. The laptop shall have a minimum battery life of XXX hours &lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;# По событию (event-driven, When)&lt;/b&gt; - требование работает как реакция на событие, обнаруженное на границе системы. Часто позволяет понять границы системы. &lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;i&gt;&lt;b&gt;When &amp;lt;trigger&amp;gt; the &amp;lt;system name&amp;gt; shall &amp;lt;system response&amp;gt;&lt;/b&gt;&lt;/i&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;Car. When the clutch pedal is depressed, the car shall disengage the driving force&lt;br /&gt;Car. When the &quot;turn indicator&quot; command is received, the car shall operate the indicator lights on the front, side and rear of the vehicle, and provide audible and visual conf irmation to the driver &lt;br /&gt;&lt;br /&gt;Laptop. When the laptop is off and the power button is pressed, the laptop shall boot up&lt;br /&gt;Laptop. When the laptop is running and the laptop is closed, the laptop shall enter &quot;powersave&quot; mode &lt;/blockquote&gt;&lt;b&gt;# По состоянию (state-driven, While)&lt;/b&gt; - требование к системе, которая находится в определенном состоянии.&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;i&gt;&lt;b&gt;While &amp;lt;in a specific state&amp;gt; the &amp;lt;system name&amp;gt; shall &amp;lt;system response&amp;gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;Car. While the ignition is on, the car shall display the fuel level and the oil level to the driver&lt;br /&gt;Car. While the key is in the ignition, the car alarm shall be inhibited&lt;br /&gt;Car. While the handbrake is applied, the wheels shall be locked &lt;br /&gt;&lt;br /&gt;Laptop. While the laptop is running on the battery and the battery is below XXX % charge, the laptop shall display &quot;low battery&quot;&lt;br /&gt;Laptop. While an external audio output device is connected, the laptop shall mute the built-in speaker and send the audio output signal to the external audio output device &lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;# По условиям (option, Where)&lt;/b&gt; - требования к системе, которая обладает конкретными свойствами&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;i&gt;&lt;b&gt;Where &amp;lt;feature is included&amp;gt; the &amp;lt;system name&amp;gt; shall &amp;lt;system response&amp;gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;Car. Where the car has electric windows, the electric window controls shall be on the driver&#39;s door panel&lt;br /&gt;Car. Where the car includes automatic windscreen wipers, the car shall sense moisture on the windscreen and operate the windscreen wipers without driver commands &lt;br /&gt;Laptop. Where a &quot;long life&quot; battery is fitted, the laptop shall have a minimum battery life of XXX hours&lt;br /&gt;Laptop. Where the laptop is a &quot;lightweight&quot; model, the laptop shall have a mass of no more than XXX grams &lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;# Нежелательное поведение&lt;/b&gt; - похоже на требования по событию&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;i&gt;&lt;b&gt;If &amp;lt;optional preconditions&amp;gt; &amp;lt;trigger&amp;gt;, then the &amp;lt;system name&amp;gt; shall &amp;lt;system response&amp;gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Car. If the car detects attempted intrusion, then the car shall operate the car alarm &lt;/blockquote&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;Car. If the car detects low oil pressure, then the car shall display a &quot;low oil&lt;br /&gt;pressure&quot; warning &lt;br /&gt;&lt;br /&gt;Laptop. If the incorrect password is entered, then the laptop shall display XXX warning message &lt;/blockquote&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;Laptop. If the laptop is connected to a non-compatible device, then the laptop shall prevent transfer of data, prevent transfer of charge, display XXX warning message and not be damaged&lt;/blockquote&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/4317379935489062012/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=4317379935489062012' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/4317379935489062012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/4317379935489062012'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/10/easy-approach-to-requirements-syntax.html' title='Easy Approach to Requirements Syntax (EARS), от Alistair Mavin '/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-6488736957268682814</id><published>2014-10-18T10:12:00.002+02:00</published><updated>2014-10-20T14:35:00.012+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Управление требованиями"/><category scheme="http://www.blogger.com/atom/ns#" term="Шпаргалка"/><title type='text'>System shall ...</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;При формулировке требований с точки зрения системы следует использовать следующую форму:&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;a href=&quot;http://www.iaria.org/conferences2013/filesICCGI13/ICCGI_2013_Tutorial_Terzakis.pdf&quot;&gt;EARS: The Easy Approach to Requirements Syntax&lt;/a&gt;, &lt;a href=&quot;http://starstoroad.com/blog/wp-content/uploads/2012/11/A_Mavin_RE10_EARS_Tutorial_slides_FINAL.pdf&quot;&gt;Alister Marvin, Rolls-Royse&lt;/a&gt; &lt;/blockquote&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;[необязательное предварительное условие] [необязательный триггер события] Система должна [ожидаемая реакция системы] &lt;/blockquote&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&amp;lt;optional preconditions&amp;gt; &amp;lt;optional trigger&amp;gt; the &amp;lt;system name&amp;gt; shall &amp;lt;system response&amp;gt;&lt;/blockquote&gt;При формулировке требования с точки зрения пользователя, хорошо работает следующая структура:&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;[класс пользователя или действующего лица] должен иметь возможность [выполнить что-то][с таким-то объектом][условия выполнения, время отклика или декларация качества].&lt;/blockquote&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;или &quot;Система должна позволять (или разрешать, или давать возможность)[название класса пользователя][делать что-то] &lt;/blockquote&gt;&amp;nbsp;Также можно посмотреть ІSO/IEC/IEEE 2011&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/6488736957268682814/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=6488736957268682814' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6488736957268682814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6488736957268682814'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/10/system-shall.html' title='System shall ...'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-8561750429892192369</id><published>2014-09-15T20:37:00.002+02:00</published><updated>2014-09-15T20:37:27.893+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Инженерия ПО"/><title type='text'>Сколько стоит плохой код</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Сколько стоит сопровождение плохого кода критической для бизнеса системы? На какие аспекты работы и сопровождения и как влияет качество кода? Что вообще такое плохой код?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Что такое плохой код? &lt;/b&gt;Собственно здесь вопрос не в вакууме, а скорее связан с сопровождением исходного кода - устранением дефектов и добавлением новой функциональности. С этой точки зрения, хороший код - это прежде всего хорошо документированный код покрытый модульными и интеграционными тестами. Хорошая документация позволяет (1) быстро найти необходимую точку приложения усилий (модуль или класс с необходимыми обязанностями), (2) убедится что код работает и увидеть ожидания от правильной работы, плюс просто посмотреть как правильно код использовать. И конечно же тестовое покрытие дает возможность рефакторинга.&lt;br /&gt;&lt;br /&gt;Есть еще конечно и просто плохой код. Такой где не соблюдаются простейшие вещи типа разделения по слоям ГУИ - БизнесЛогика - Хранение, закона Деметры и прочих вещей типа SOLID. Но, думаю, такого кода в продакшене не много.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Документация это долго, все постоянно меняется, документация устаревает ...&lt;/b&gt; и т.п. - отговорка - просто нежелание делать свою работу. Простейшего комментирования классов, методов и атрибутов уже достаточно, чтобы какой-нибудь XDoc инструмент перечислил пакеты и их содержимое, иерархию наследования ... а если пакет продвинутый то и диаграммы классов и зависимостей можно получить&amp;nbsp; довольно быстро и при малых трудозатратах. Все это элементы простейшей культуры разработчика.&lt;br /&gt;&lt;br /&gt;Особенно это важно, просто критично, когда система сложная с большим количеством объектов и сложной объектной иерархией.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Какое влияние оказывает?&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Временная задержка&lt;/b&gt;, которая нужна для подготовки нового разработчика. Чем хуже код и больше нюансов - тем больше времени требуется чтобы из новичка получить полноценную единицу FTE. Еще очень важный момент, что новый разработчик некоторое время (зависит от степени сложности, плохости кода) начинает отвлекать полноценного FTE от его текущих задач - вместо единицы хорошо если остается четверть. Т.е. прямо по Бруксу - если вы хотите повысить скорость внесения изменений - простое добавление разработчиков вас только замедлит на время адаптации в коде новых разработчиков. Равно падении скорости минимум в два раза на период адаптации. Проблему команды разработки можно легко перенести на команду тестирования - все тоже самое.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Скорость внесения изменений по исправлению дефектов и доработке фичеров&lt;/b&gt;. Чем хуже код, тем более он подвержен плывучести, такой что небольшое изменение затрагивает десяток файлов исходников. Хорошая практика - посмотреть историю комитов в хранилище исходного кода связанных с фиксами и доработками и посмотреть сколько файлов и в каких местах было изменено в процессе запроса на изменение. Наверняка, есть даже какие-то показатели и надо бы погуглить.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Особые случаи, когда ваще плохой &lt;/b&gt;... уже в продакшене, и это бизнес-критикал ПО&lt;br /&gt;&lt;br /&gt;Здесь приходится еще помогать на уровне продакшена, и опять если это сложно, делают это наши эксперты разработчики, отвлекаясь от задач разработки на проблемы продакшена (пользователей и зависимых систем).&amp;nbsp; Разработка стоит.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Совсем тяжелый случай&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Когда без существенного реинжиниринга существующей кодовой базы, начинается масштабная доработка вроде поддержки нового слоя взаимодействия. например просто СУБД или учетной системы, или второго ГУИ, типа мобайл или веб. Все просто - система работает, реинжиниринг придумали чтобы ничего не делать и т.п.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Что делать?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;А нечего тут делать - нужно замораживать разработку новых фичеров и делать реинжиниринг. Или все равно делать реинжиниринг отдельной командой, параллельно с потоком поддержки. Бросить систему как есть нельзя - бизнес-критическая. &quot;Переделывать нельзя поддерживать&quot; запятые пусть каждый расставит сам.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/8561750429892192369/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=8561750429892192369' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/8561750429892192369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/8561750429892192369'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/09/blog-post.html' title='Сколько стоит плохой код'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-7372495739303748727</id><published>2014-09-11T00:34:00.000+02:00</published><updated>2014-09-12T11:59:51.199+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Разработка"/><title type='text'>Ruby defensive programming</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;b&gt;upate 12.09: статистика после добавления expect! &lt;/b&gt;Переписал проверку аргументов через expectation expect - 65 (было 83 - снижение на 22%) runs, 96 (было 117 - снижение на 18%) assertions, 0 failures, 0 errors, 0 skips. Также заменил attr_accessor на типизированное свойство - как следствие удалил несколько &#39;setters&#39;. В сухом остатке - &lt;b&gt;20%-е снижение затрат на тестирование&lt;/b&gt;.&lt;/blockquote&gt;&lt;br /&gt;Вчера закончил модули ISPS::Core и ISPS::Data. Написаны все базовые классы, написаны тесты (&quot;rake test&quot; говорит о 83-х тестах и 117-ти проверенных утверждениях). В этой точке решено было сделать небольшую остановку и тщательно задокументировать (написать комментарии для генерации документации) все классы и добавить примеры использования. И насколько это возможно с сегодняшними знаниями Ruby, попытаться переосмыслить написанный код.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;# Интерпретатор и текстовый редактор vs Компилятор и IDE.&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;Сразу скажу, что опыта плотной работы с интерпретаторами у меня до этого момента не было. Начинал программировать я в средней школе на интерпретаторе BasicA, вшитом в ПЗУ компьютера IBM PS/2 30 :) Но очень непродолжительный был этап, и подробностей не помню. А вот Turbo Pascal 5.5 помню :) Дальше было много всяких разных языков на которых работал и просто баловался - С++, Delphi, C#, Java (и докатился до Ruby). Все они строго-типизированные, и можно сказать, что подход не слишком отличается - компилятор - статическая проверка кода при компиляции выявляет синтаксические ошибки и несоответствия типов и тыкает в строку кода с ошибкой. ну и плюс разные вкусности CodeIntelligent - дополнение кода, рефакторинг, навигация по методам и т.п.&lt;br /&gt;&lt;br /&gt;Вообще подобные достижения CodeIntelligent уже дошли и до интерпретаторов, возможно не настолько качественно как для Компиляторов, но все-таки дошли. Даже синтаксис как-то проверяется, например тот же Linter, который я все-же отключил :) Но несмотря на значительные успехи, до этапа запуска скрипта все ошибки отловить думаю просто невозможно (отладчиком в Ruby я также пока не пользовался, стремно как-то в командной строке дебажить :))&lt;br /&gt;&lt;br /&gt;ИМХО, поэтому для интерпретаторов крайне важны модульные тесты - без них просто никак. Т.е. если не пройти каждую ветку исполняемого кода, не исполнить ее при помощи теста, уверенности в 100% работоспособности кода нету. Можно просто запустить интерпретацию класса, она завершится успехом и никаких ошибок не возникнет. НО они возникнут потом в конкретном куске кода, причем часто довольно смешные и нелепые :) Так что тестового кода нужно писать много. И если на Делфи я тестировал в основном корректность логики выполнения, то для Ruby  прежде всего нужно убедится что он просто выполняется :) И возиться с этим стоит, т.к. Руби чертовски легкий, лаконичный, приятный и мощный язык с очень развитым сообществом и огромным количеством готового кода.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;# Полностью объектный язык&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;В Ruby нет примитивных типов, вроде Integer, Boolean, String, Date, все это полноценные объекты, унаследованные от класса Object. В Ruby нет строгой типизации. С одной стороны это довольно удобно, упрощает многие задачи. Однако в моем случае отсутствие строгой типизации, и большая привычка к ней, возможно сыграли злую шутку. Около 10% кода - проверка на допустимый тип аргумента функций. Около 20% тестового кода - проверка того, что работают проверки на тип аргумента ... прямо фракталы какие-то :)&lt;br /&gt;&lt;br /&gt;В общем пыхтел, писал и даже получилось что задумал, и даже получил удовольствие от процесса. Тестовый код проверки аргументов функций меня беспокоил, сама проверка также. И вот я смотрел справку по Yardoc и увидел объявление макроса для ... позже &quot;узрел корень&quot;, что макрос создается для функции аля attr_accessor, которая кроме имени атрибута принимает параметром его тип - &quot;property :my_property, String&quot;. Присмотрелся немного, идея понравилась и я тут же &lt;a href=&quot;https://gist.github.com/nvoynov/4629ca67fc439e2916d5&quot;&gt;изобрел свой первый велосипед для атрибутов&lt;/a&gt; - стал передавать тип, и проверять соответствие в методах присвоения значений :)&lt;br /&gt;&lt;br /&gt;Радовался не долго, т.к. решил только половину проблемы о которой&amp;nbsp; раньше не сильно задумывался - просто увидел в сгенерированной документации, что все атрибуты имеют тип Object и побежал решать проблему. Второй, более актуальной частью проблемы оставалась проверка на соответствие типов аргументов при вызове методов (и тестирование, что проверка работает :)). Здесь я вспомнил про &quot;защитное программирование&quot; и про то, что все уже написано - ну и за пару минут нашел нужный гем на RubyToolbox - &lt;b&gt;&lt;a href=&quot;https://github.com/radiospiel/expectation&quot;&gt;expectation&lt;/a&gt;&lt;/b&gt;. Тут же немного &lt;a href=&quot;https://gist.github.com/nvoynov/811fc432f9874ea1a508&quot;&gt;упростил код велосипеда&lt;/a&gt; и пошел листать &lt;a href=&quot;http://radiospiel.org/expectation/&quot;&gt;презентацию&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Теперь можно вздохнуть спокойнее - если нужна более строгая типизация - это можно легко исправить. И если есть гем из коробки - можно вполне посчитать что он работает как нужно, и не писать больше тестового покрытия для проверки типов атрибутов :) Так что пора наверное сделать &quot;git checkout -b maintenance/refactoring&quot;, где переписать утверждения на ожидания и избавится от части тестового кода.&lt;br /&gt;&lt;br /&gt;Про поддержку тестовой базы пока ничего сказать не могу. Ожидается, что это будет небольшой адЪ, но я пока напоролся только однажды, когда добавил немного параметров в конструктор одного объекта. &lt;br /&gt;&lt;br /&gt;Вот такие пока пироги.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/7372495739303748727/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=7372495739303748727' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/7372495739303748727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/7372495739303748727'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/09/ruby-defensive-programming.html' title='Ruby defensive programming'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-6170438328273369152</id><published>2014-09-10T01:43:00.002+02:00</published><updated>2014-09-10T01:43:28.287+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="Провижининг"/><title type='text'>Ruby internet provisioning persistence</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Только что закончил последние тесты к слою хранения. Это демо-продукт, и СУБД вообще не планировал трогать. Сейчас есть абстракция для базы данных и ее реализация для yaml. ИМХО, для Демо &quot;за глаза&quot; (картинки будут ниже). Но несколько соображений по теме хранения для реального проекта все-таки стоит привести.&lt;br /&gt;&lt;br /&gt;Вообще могу сказать только за RDBMS. Про NoSQL только слышал, но не использовал и пока не понимаю для каких задач они полезны.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;# Несколько утверждений:&lt;/b&gt;&lt;br /&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Каждый продукт провижининга - это объект со сложной внутренней композицией в которую входят: продукты, подпродукты и составляющие их компоненты; экземпляры продуктов, функции в качестве условий и параметров компонентов; функции, параметры которых также вычисляются через функции ... и это только статическая составляющая, еще нету действий, нету версионности продуктов ...&lt;/li&gt;&lt;li&gt;Работа по созданию\изменению продуктов отделена от работы по выполнению заказов продуктов абонентами. Каждый продукт создается, и тщательно тестируется по совместной работе в комбинации другими продуктами. После чего существует уже готовый. Каждый продукт создает и тестирует один человек&lt;/li&gt;&lt;li&gt;Все продукты провижинига должны загружаться целиком при старте системы, чтобы не терять время на загрузку продукта из базы для каждого заказа продукта.&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;# Хранение объектов в RDBMS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Вообще темы хранения объектов в реляционных структурах не касался все то время которое не занимаюсь разработкой, но не думаю, что за эти семь лет произошла какая-то революция. Поэтому вижу старую стандартную проверенную схему, примерно следующую:&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;OBJECT_TYPE(ID, NAME) &lt;br /&gt;OBJECTS(ID, OBJ_TYPE_ID, OBJ_NAME, DESCRIPTON, PARENT_ID, INSTANCE_ID)&lt;br /&gt;OBJECT_PARAMS(ID, OBJ_ID, PARAM_NAME, PARAM_VALUE)&lt;/blockquote&gt;Для нашей маленькой демо-системы, можно даже прикинуть. Пусть будет около 10 продуктов (4 ТП, и 6 услуг). Пусть в каждом продукте будет по 10-15 элементов и 3-4 экземпляра (разные ветви по различным условиям и состоянию абонента). У каждого элемента пусть будет 10 параметров (стандартные параметры, условия, ...) Получим около 3000-6000 объектов - даже для простой СУБД мелочь. Однако, если попробовать масштабировать на настоящую компанию и подобную систему - все будет немного тяжелее.&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Будет несколько групп абонентов- часники\юрики\корпоративные клиенты - соответственно условия для них будут отличаться и по этому параметру количество продуктов увеличится грубо в три раза.&lt;/li&gt;&lt;li&gt;Будет реальная биллинговая система, где будет не 5 основных параметра, а 10. - в два-три раза увеличивается количество элементов в продукте&lt;/li&gt;&lt;/ul&gt;Итого, 10 продуктов * 30-50 элементов (добавим функции и их параметры!) * 4 экземпляра * 10 параметров = 12000 - 20000 ... ну тоже не критично - смешной объем для хранения, но этот объем нужно загрузить сразу при старте системы. А после загрузки, нужно будет собрать из этих трех таблиц реальные продукты ... на этой уйдет время.&lt;br /&gt;&lt;br /&gt;Изменяться продукты будут крайне редко и только одним пользователем одновременно. ПРОЩЕ И ПРАКТИЧНЕЕ ХРАНИТЬ СРАЗУ ГОТОВЫЙ СЕРИАЛИЗОВАННЫЙ ОБЪЕКТ ПРОДУКТА, только в человекочитаемом формате, так чтобы можно было прочитать и внести изменения туда просто руками в текст. Плюс загружаться такой объект будет один на каждый продукт. Т.е. мне кажется подойдет некоторая гибридная схема (ниже) - думаю, 10 записей продуктов с десериализаций будет быстрее чем фетч 20000 строк и последующая сборка продуктов. И ГЛАВНОЕ не будет лишнего кода преобразования ООП-РДБМС&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;OBJECTS(ID, OBJ_NAME, SERIALIZED_OBJ)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Вот так сел сначала&lt;b&gt; &lt;/b&gt;с намерением рассказать ощущения от программирования на интерпретируемом ЯП в текстовом редакторе, но получился пост про слой хранения.&lt;br /&gt;&lt;br /&gt;... А вот и обещанные картинки, которые нам построил GraphViz по файлу, который подготовил нам Yard ... и думаю может репозиторий переименовать в Ruby internet provisioning (RIP) ..&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-3qRALKDsoV4/VA-PUh5qkaI/AAAAAAAAS0g/haT_byDqtTc/s1600/core.dot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-3qRALKDsoV4/VA-PUh5qkaI/AAAAAAAAS0g/haT_byDqtTc/s1600/core.dot.png&quot; height=&quot;134&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-MdTGoRZ_5mw/VA-PX-V7S7I/AAAAAAAAS0o/OjbHdgjQL_A/s1600/data.dot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-MdTGoRZ_5mw/VA-PX-V7S7I/AAAAAAAAS0o/OjbHdgjQL_A/s1600/data.dot.png&quot; height=&quot;103&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/6170438328273369152/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=6170438328273369152' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6170438328273369152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/6170438328273369152'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/09/ruby-internet-provisioning-persistence.html' title='Ruby internet provisioning persistence'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-3qRALKDsoV4/VA-PUh5qkaI/AAAAAAAAS0g/haT_byDqtTc/s72-c/core.dot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5553879771699141855.post-4712641790183413312</id><published>2014-09-07T01:16:00.001+02:00</published><updated>2014-09-07T01:16:26.874+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><title type='text'>Какая красота этот Ruby Forwardable</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;Думаю многие помнят про &quot;Закон Деметры&quot;? В Руби есть прекрасный модуль Forwardable который легко и не принужденно выведет методы внутренних объектов на поверхность родительского класса.&lt;br /&gt;&lt;br /&gt;Самый простой пример коллекции ...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src=&quot;https://gist.github.com/nvoynov/2d37ffddd595fe42fcf1.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;b&gt;ЗЫ&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Язык с каждым новым открытием нравится все больше и больше&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nvoynov.blogspot.com/feeds/4712641790183413312/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5553879771699141855&amp;postID=4712641790183413312' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/4712641790183413312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5553879771699141855/posts/default/4712641790183413312'/><link rel='alternate' type='text/html' href='http://nvoynov.blogspot.com/2014/09/ruby-forwardable.html' title='Какая красота этот Ruby Forwardable'/><author><name>Николай Войнов</name><uri>http://www.blogger.com/profile/16140057004388003216</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_IWZZIEvrm2A/TNv0PDiJCkI/AAAAAAAAGJc/dwUC5mx47Ec/S220/11-1.jpg'/></author><thr:total>0</thr:total></entry></feed>