Автор: vit

  • Про Android TV.

    androidTV_player-entertainment-default

    Небольшая предыстория.

    Так получилось, что мы пишем приложение для Android TV.
    Вообще, обычно я занимаюсь тем, что в программисткой среде принято называть “суровым энтерпрайзом” — веб-службы, высокая нагрузка и прочие Java EE штуки.

    Тем не менее, иногда мы делаем проекты и под мобильные платформы. Как правило это заказная разработка, например мобильные приложения для внутренних нужд компании (приложения для сотрудников организации/диспетчеров/водителей, интерактивные учебные пособия, системы учета/бронирования, системы мониторинга и так далее), которые потом обычно и интегрируют с бэкендом на “суровом энтерпрайзе”. Этими приложениями пользуется персонал компании, а не простые пользователи. В большинстве случаев они даже не публикуются на маркете.

    Естественно из этого есть исключения.
    Итак. Да, мы пишем под Android TV. Не знаю, много ли существует мобильных разработчиков в России, которые что-то делают под эту платформу. Понятное дело, есть крупные компании, которые занимаются производством и распространением телевизионного и медиа контента и им сам Бог велел заниматься созданием приложений под эту платформу. Когда-то давно, я тоже делал мобильное приложение для одного популярного в определенных кругах телеканала, но сейчас не об этом.

    У нас немного другая история. Мы изначально делали обычное приложение (с кнопочкам и картинками), и по началу думали, что оно будет работать на телефонах, планшетах и китайских свистелках-поделках – “тв приставках”. Потом внезапно выяснилось, что платформа Android TV подошла на удивление хорошо для целей проекта.

    Про Android TV.

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

    1. Нормального эмулятора нет (как обычно). Мы используем оригинальный, привезенный нам из забугорья Android Nexus Player. Настоящий суровый американский Nexus Player с плоской вилкой на 110 В. Без намёка на РОСТЕСТ. Без такого устройства нормальная разработка под Android TV была бы затруднительна. Как и все Nexus-ы он неплохо подходит для целей отладки и разработки. Нет проблем с драйверами, подключением по adb и т.д. Это наше основное девелоперское устройство в этом проекте.

    2. Конечно мы проводим бета-тесты еще и на телевизоре Sony. Как выяснилось, это вполне такой обычный телевизор, просто на нем установлен Андроид.
    Естественно кроме телевизора и Nexus-а, перед тем как выложить приложение, нам приходится тестировать приложение на десятках разных телефонах и планшетах (те кто пишет под Андроид знают, что это не гипербола, а суровые будни андроид программиста).
    Так вот, на телевизоре что-либо дебажить очень не удобно, поэтому опять таки основным устройство у нас является Nexus Player.

    3. В какой-то момент Nexus Player внезапно обновился на Marshmallow (Android M) (что в прочем для нексусов вполне типично).
    В итоге у нас в руках появился очень редкий, можно сказать “краснокнижный” зверь. Устройство под Android TV (которых мало) и с 6-ой версией Android-а (которых еще меньше). Это прямо-таки удивительное и непредсказуемое создание. Часто было не понятно, особенности в его поведении были связанны с тем, что это был шестой андроид или потому, что это Android TV.

    Выводы.

    Стоит ли писать под Android TV? Думаю решать нужно исходя из целей проекта. Приведу свои, субъективные размышления на эту тему (актуально на момент публикации этой статьи).

    1. ТВ стали смотреть меньше. Возможно я ошибаюсь, но это общий тренд. Я не уверен, что в будущем вообще будут много смотреть телевизоры.
    2. Играть на Android TV в игры – сомнительное удовольствие. Я конечно не геймер, но мне кажется, что уж лучше подключить XBox.
    3. Платформа требует отдельного внимания и тщательного изучения API.
    Текстовый ввод не удобен (т.к. пульт). Если у вас много элементов управления (текстовых полей, кнопок) или используется тач, то придётся все эти моменты перерабатывать.
    4. Аудитория. Может я не прав, но если сравнивать со всей массой пользователей андроид устройств её почти нет.
    Вживую телефон с андроидом я видел у многих. Телевизор с Android TV только один.
    5. Как операционная система Android для телевизоров удобней чем Smart TV. Это лично мое мнение, я могу сравнить, т.к. дома у меня телевизор LG с webOS, а на работе тестируем на Sony с Android-ом.

    Мое личное мнение, использовать Android TV приложения, только в том случае, если это действительно вам подходит.
    Сил и времени потратите уйму. Если делать по-уму, нужно оптимизировать пользовательский интерфейс (иначе приложением нельзя будет пользоваться), обрабатывать нажатие с пульта, менять систему навигации и многое другое.

    Стоит ли следить за развитием платформы? Да, однозначно стоит. Бросить всё, уволиться с работы, продать машину и квартиру и начать делать ещё один клон “ангри бёрдс” под Android TV, в надежде что он вас озолотит — на мой взгляд не самая здравомыслящая идея.

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

    PS: Хотел уточнить, чтобы не возникло искаженное понимание ситуации, т.к. я с одной стороны критикую платформу, а с другой стороны пишу что мы под нее активно разрабатываем. Да я считаю, что нет особого смысла в обычных приложениях под Android TV. У нас совсем другой случай, мы делаем специализированный продукт для B2B-сектора по заказу. Другими словами, пишем приложение специально предназначенное для работе на телевизоре.

  • FWD: Just Say mNo to Hungarian Notation!

    mNo

    Не могу пройти мимо призыва Джейка Вартона – “Скажи mNo венгерской нотации!“.

    Во-первых (и это мое личное мнение), использовать такую нотацию в исходниках на Java действительно нелепо.
    Во-вторых, когда-то давно я grep-ом проходил исходники андроида (кажется 16-ый API Level) и там нотация не соблюдалась. Более того она была некорректной (статические поля с m-префиксом).

    Вартон молодец, что наконец-то поднял эту тему.

  • Заметка об экспериментах со SnappyDB (NoSQL KeyValue DB под Android)

    Небольшая заметка про SnappyDB. Это NoSQL база данных под Android, которая базируется на LevelDB и алгоритме сжатия Snappy.

    LevelDB – это key-value база данных. Написана Google-ом для каких-то своих мега проектов.
    Snappy – метод сжатия данных, сбалансированный на скорость (т.е. приоритет быстрота, а не степень сжатия). Также написана Google-ом.

    Авторы SnappyDB на своем блоге приводят очень привлекательный график сравнивая скорость работы SnappyDB с SQLite.

    Все это конечно очень и очень заманчиво, но лично меня она заинтересовала не поэтому. Дело не в скорости и даже не в том, что какие-то части этой БД делал Сам Google, а в более-менее нормальном API.

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

    Конечно по-хорошему можно использовать API Preferenes или SQLite, но в некоторых случаях это не очень удобно.
    В частности у SQLite несколько громоздкий API, а в preferences нет удобных методов для сложных выборок по ключам.

    Упоминая более-менее нормальное API я имел в виду следующее. Вот что нужно сделать чтобы получить значение по ключу в Preferences (Android API).

      SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
      String username = sharedPref.getString("name", "");
    

    Вот что нужно сделать чтобы получить значение по ключу в Snappy DB.

      DB db = DBFactory.open(context); 
      String username =  db.get("name");
    

    Другими словами, API не такое “многословное” как стандартное Android API.

    При этом если есть несколько записей (“name:0″,”name:1″,”name:2” и т.д.), то их можно получить как-то так:

      db.findKeys("name:");
    

    Такое “из коробки” в Preferences сделать пока невозможно.

    Поэтому мне показалось, что Snappy DB это удобно. Можно использовать например в таких задачах как:
    – Сохранить справочников кодов и их описание
    – Запоминать время работы каких-то специальных команд или хранить данные по мониторингу
    – Идентификатор пользователя и его профиль (например в XML или JSON формате)

    В общем все было хорошо, пока не наткнулся на одну приставку под Android TV, на которой был установлен Android M. Так вот, на этом устройстве Snappy DB внезапно стала работать с ошибками. Поскольку БД нативная, а желания дебажить сишный код у меня в последнее время нет, пришлось отказаться от ее использования в текущих проектах.

  • Мини-пост про scala туториал

    Какая-то компания (udemy.com) прислала ссылку на их тьюториал по Scala и попросили разместить её, т.к. нашли мой старый вольный перевод на русский язык мини-учебника по Scala. Думаю поэтому они предположили, что возможно я релевантен или читали этого блога релеванты…

    Если честно, лично я делал ту старую публикацию когда вел курс по выбору на физтехе (практикум по программировнию на Scala/Java) и хотел, чтобы у моих студентов был хоть какой-нибудь учебный материал по Scala на русском. Было это лет пять назад.

    Сейчас со Scala сталкиваюсь меньше. Изначально в Scala были вещи которых мне очень не хватало в Java. С выходом Java 8 острая необходимость в Scala у меня отпала.
    Тем не менее Scala довольно интересный язык, на рынке труда востребован, так что может этот учебник кому-то поможет в его изучении.

    Вот ссылка на тот туториал, который мне прислали.

    PS: Спросил собираются ли они делать перевод на русский язык, пока жду ответа.

  • Шаблонизатор mustache и Java.

    mustache

    В этом году решил изменить вековые традиции и в Java проектах начать использовать вместо велосити (анг. Apache Velocity) популярный хипстерский мусташ (анг. Mustache). Дело в том, что в обычной жизни я, как правило, обхожусь вообще без шаблонизаторов и в простых случаях использую регулярки (regexp-ы). Когда нужно использовать сложные шаблоны для генерации текстовых файлов, то подключаю велосити (просто потому, что “рука набита”).

    В этот раз нужно было что-то среднее. С одной стороны, не такое тяжеловесное, как велосити, а с другой стороны… не хотелось все делать руками. В итоге выбор пал на Mustache. В историческом обзоре на википедии написано, что изначально Mustache был сделан для рубистов. Тем не менее, позже он стал крайне популярен на фронтендэ у JavaScript-eров (и не только), и сейчас пользу от его использования сложно переоценить. Более того, если зайти на сайт Mustache, то можно узнать, что он реализован на 30+ языках программирования. Естественно Java также присутствует среди них. Если быть точным, то на сайте у них Java на десятом месте (между Objective-C и C#). Стоит отдать должное создателям java версии библиотеки. Хотя она занимает не первое место в списке, но находится, как и документация к ней, в весьма удовлетворительном состоянии. Установить библиотеку и начать с ней работу особого труда не составляет: jar-ик подключается через мавеновский репозиторий.

    В качестве отличительных особенностей самого шаблонизатора можно указать следующие:

    Во-первых, символами, обрамляющими метки-заполнители (placeholder-ы), являются фигурные скобки “{“. Визуально они чем-то напоминают усы (анг. mustache), повернутые на 90 градусов.
    Выглядит это так:

    Hello {{name}}
    You have just won {{value}} dollars!
    {{#in_ca}}
    Well, {{taxed_value}} dollars, after taxes.
    {{/in_ca}}
    

    Во-вторых, основная идея mustache состоит в logic-less подходе. Под этим авторы подразумевают отсутствие различных if-else конструкций, а также циклов. Другими словами, вот такие велоситивские штуки не пройдут:

    ## Пример для Veloctity
    #if( $foo < 10 )
        Go North
    #elseif( $foo == 10 )
        Go East
    #elseif( $bar == 6 )
        Go South
    #else
        Go West
    #end
    

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

    1. Берем шаблон.
    2. Передаем данные. В случае Java это обычный Map.
    3. Смотрим на ключ. Проверяем значение.
    3.1. Значение является строчкой? Показываем.
    3.2. Значение является пустым списком, false или отсутствует? Не показываем.
    3.3. Значение является список (точнее Iterable)? Проходим по каждому элементу списка и применяем для него правило.
    3.4. Значение является Callable? Получаем функциональщину.

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

    В ней детально изложены различные практические аспекты.
    Например:
    – Что делать, если вы хотите эскейптить HTML символы? Или не эскейпить?
    – Что делать, если вы хотите выводить что-то в случае отсутствия данных (Inverted section)?
    – Что делать, если вы хотите делать какую-то “предварительную” обработку данных, перед показом?
    и т.д.

    В-третьих. Сама структура библиотеки и ее архитектура оказались достаточно гибкими. Например, если есть желание хранить/загружать шаблоны из своего спецхранилища (а не только из файлов или загрузчиков классов), то можно сделать свою реализацию MustacheResolver. Другими словами, архитектура библиотеки более-менее сбалансированная. Не слишком много “абстракций”, но при этом сохранилась необходимая гибкость.

  • Android Design Support Library

    Наконец Google сделал эту библиотеку с материальными виджетами!

    Важно!
    Возможно в официальной документации developer.android.com ошибка.
    Вместо:
    ‘com.android.support:support-design:22.0.0′

    нужно указывать:
    ‘com.android.support:design:22.2.0′

  • Про Gradle для любопытных.

    Предыстория.

    Вот раньше был Ant. Простой и понятный инструмент для сборки проектов. Открываешь xml-ку и видишь: здесь мы хотим скомпилировать файлы, здесь скопировать всё в папку dist, а здесь сделать jar-ик.

    Потом придумали Maven. Это была небольшая революция. Искать и подключать популярные библиотеки стало намного проще. Все стали использовать приблизительно одинаковую структуру проектов (исходники хранились в одной папке, конфигурационные файлы – в другой, тесты – в третьей).

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

    Разобраться, как работает Maven; понять, что означают все эти тэги – было весьма затруднительно. Всё взаимодействие ограничивалось, как правило, запуском команды mvn clean install. Для многих это действие означало что-то похожее на взмах волшебной палочки с параллельным произнесением заклинаний: “Expelliarmus” или “Avada Kedavra“.

    Любая проблема, требующая каких-либо нестандартных исправлений в pom.xml, первым делом решалась поиском “нужного заклинания” в stackoverflow или Google. Главная причина недовольства, которое высказывали многие программисты, что не понятно как и в какой последовательности всё работает. Например, что нужно сделать, чтобы просто скопировать файлик и затем выложить его на ftp (или запустить обфускатор)?

    Тем не менее, Maven постепенно занял свое место в умах людей. Кто-то из любопытствующих и упорных в итоге разобрался в его внутреннем устройстве. Кто-то просто свыкся. Но время идет, мода меняется. Находятся люди, для которых уже и Мaven – это неудобный и даже архаичный инструмент.

    Время не щадит никого…
    (далее…)

  • Про FOP, SVG, PDF и значение дизайна.

    Коворкинг интересен тем, что в нем можно встретить интересных людей.
    Следующая история произошла после краткой беседы с Димой Гарником, арт-директором небольшой дизайн-студии.
    У Димы была идея создать простой сайт для автовизиток. Идея несложная, но интересная. Вы заходите на сайт, указываете номер телефона и сообщение (например: “Мешает машина? Звони!“). Затем вы получаете развертку, из которой можно собрать симпатичную машинку. Развертка – это PDF-файл, который можно распечатать на листе бумаги формата А4 и собрать. Самое главное: сборка идет как “оригами”, т.е. без ножниц и клея, нужны только “прямые” руки и время.
    В итоге получается такая штука:

    car_2
    Собственно, нужно было как-то реализовать генерацию этих разверток.

    Так совпало, что Дима подошел и рассказал про свою идею именно в тот момент, когда мы с соседом пили кофе и вели досужие разговоры на тему: “что бы такого сделать интересного и не сложного”. Димина идея показалась интересной и не очень трудоемкой.
    Генерацией PDF-файлов мне уже приходилось заниматься в прошлом (хотя это и была, в основном, генерация документов и отчетов с использованием различных выборок из БД – принципиальной разницы я не видел).

    В общем, я сделал эту штуку.

    Про FOP, SVG, PDF

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

    1. Берем рисунок в векторе.
    2. Сохраняем его в SVG-формате.
    3. Поскольку SVG – это обычный XML, то менять в нем содержимое (номер, сообщение, цвет и т.д.) несложно.
    4. Прикручиваем преобразователь SVG → PDF.
    5. Проверяем, что все это работает, и делаем к этому “обвес”, который обрабатывает HTTP запросы и отдает пользователю PDF-файл.
    6. Прикручиваем дизайн или интегрируем с текущим сайтом.

    В целом, все прошло согласно плану. За исключением следующих моментов:

    1. Проблемы со шрифтами.
    Конечно, все зависит от SVG-файла, но, возможно, возникнут сложности с кириллическими шрифтами после развертывания на сервере (т.е. на Linux-е).
    Решение: поставить недостающие (зависит от того, какие нужны) шрифты.
    Например, как-то так:

    apt-get install ttf-mscorefonts-installer

    2. Еще раз проблемы со шрифтами.
    У того, кто раньше работал с Apache FOP, могут возникнуть сложности в более тонкой настройке конфигурации.
    Дело в том, что формат файла для настройки PDFTranscoder-а отличается от привычного fop.xconf!

    Если кратко:

    //Создает перекодировщик. Кроме PDF, если верить документации есть перевод в PostScript, EPS.
            Transcoder transcoder = new PDFTranscoder();
    
            // Если нужно "вшивать" свои шрифты, требуется дополнительная настройка
            try {
                DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
                Configuration cfg = cfgBuilder.buildFromFile(new File("pdf-renderer-cfg.xml"));
                ContainerUtil.configure(transcoder, cfg);
            } catch (Exception e) {
                throw new TranscoderException(e);
            }
    

    Где “pdf-renderer-cfg.xml”:

    
    
      
        
          
        
      
    
    

    Весь пример можно скачать с сайта Apache FOP.

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

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

    Про дизайн.

    Есть такая замечательная статья Learning to see (Учимся видеть)
    В ней приводится следующая диаграмма:
    chart

    Как правило, чем более “программистская” контора, тем сильнее доминирует принцип – делаем “not pretty but functional“, а затем дизайн (если остались деньги).
    Все бы хорошо, но бывают заказчики, которым потом жалко тратить деньги на нормальный дизайн: им главное, чтобы работало. Как правило, это касается разработки внутренних систем. В целом, это нормальная бизнес-ситуация: лишних денег на “красивости” часто нет. Правда в том, что в итоге сотрудникам некоторых компаний приходится годами пользоваться унылым корпоративным ПО.

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

    pod_steklom_bold
    Без дизайна

    Для сравнения, вот так он выглядит сейчас:

    pod_steklom_beauty
    С дизайном

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

    Красиво выглядит? Да, бесспорно! Работает? К сожалению, нет. При этом могут пройти месяцы, пока из красивого получится работающее. Ситуация может усугубиться, если дизайнер “понапридумывает” разного, а это потом не будет работать или окажется невозможным реализовать.

    Многие скажут: “К чему эти банальности? Это и так понятно!”. Понятно, но хотел бы повторить: нормальный дизайн – это не опция, это неотъемлемая часть хорошего программного продукта. Такая же составляющая, как и его функциональность.

    PS: Может кто-то знает нормальные курсы дизайна по UI/UX? Не про “сферического коня в вакууме”, а про конкретные практики – как пользоваться инструментами. И не про общие принципы: что нужно выравнивать, что какие-то цвета плохо сочетаются и т.д., – про это многое уже известно.
    Проблема в том, что иногда по мелочи нужно что-то сделать (например, у меня бывают вопросы, как в фотошопе кнопку перекрасить из серого в красный) и это вызывает определенные сложности. Спасибо соседям по коворкингу, что выручают (Николай, Надежда – это я про вас ;).
    В общем, если кто-то из программистов, читающих мой блог, бывал на таких курсах – был бы рад услышать про них отзыв: стоит или нет.

    PPS: Если, вдруг, какой-то дизайнер забредет на мой программистский блог – буду рад возможности сотрудничества. Пишите в комментариях ;).

  • Обновление времени в Java.

    Заметка об обновлении времени, на которую у меня все никак не хватало времени. 1419292146_clock

    Речь идёт о смене временных зон для Oracle JDK/JRE. Такие изменения могут быть вызваны например отменой летнего/зимнего времени, сокращением часовых поясов за счет их объединения и другими обстоятельствами.
    Для этих целей можно использовать Timezone Updater Tool.

    Чтобы выполнить обновление нужно выполнить следующие шаги:
    1. Загрузить с сайта jar-ик (http://www.oracle.com/technetwork/java/javase/downloads/index.html).
    tzupdater_download

    2. Затем запустить из консоли как обычную java-программу с ключами -u -v:

    java -jar tzupdater.jar -u -v
    -u означает обновить (update)
    -v для показа дополнительной детальной информации (verbose).

    Естественно, если у вас несколько JVM, то сначала нужно разобраться, какую конкретно вы хотите пропатчить. Поэтому на всякий случай проверьте, что конкретно указано в bat- или sh-скриптах которыми вы запускаете сервер и какая именно java запускается.

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

  • Оборачиваясь назад.

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

    Дело в том, что общаясь в среде различных программистов с завидной периодичность наблюдаю следующую сцену. Один разработчик рассказывает и показывает итоги своей работы другим программистам в надежде получить отзыв вроде: “Ну ты крууууут!“, в ответ же он получает не возгласы восхищения и аплодисменты, а вопрос: “На что именно было потрачено столько времени? На ЭТО? Что тут такого делать, почему так долго?“. После этой фразы начинаются жаркие споры, обиды, непонимание и обвинения в некомпетентности друг друга.

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

    Более того, сами программисты спустя годы, оборачиваясь назад начинают думать: “Я потратил на это три/пять/семь лет своей жизни? Почему?! Как ЭТО заняло столько времени?

    Одной из причин, на мой взгляд, является не совсем точное представление о том, как оценивается сложность проекта. Для многих это прямая из точки А в точку B.
    Пред глазами предстает следующая картинка.
    ab

    На самом деле, это идеальная картина. В жизни разработка сложного проекта сопровождается решением многих неучтенных проблем. Возникают “развилки” на которых нужно принимать решение куда двигаться дальше. Это могут быть решения высокого уровня, такие как выбор языка (java, c#, python или всё вместе) или способ хранения данных (mysql, oracle, berkley db, mongodb, hazelcast или все вместе), так и более низкого уровня – какой веб-фреймворк выбрать (ext или gwt, или может быть JSF 2 и т.д.), прикрутить velocity или обойтись стандартными средствами для работы со строками, начать использовать более популярный graddle или остаться на maven-е (или даже ant-e), использовать AnglularJS или не стоит.

    Таких “точек бифуркации”  в большом проекте может быть несколько десятков или даже сотен. При этом важно понимать, что все могут ошибаться и иногда приходится возвращаться на исходную позицию, менять стратегию, платформу (или как говорят программисты “переписать половину кода”). Кроме этого цель из точки B может передвинуться в точку B’ и в результате некоторые принятые решения уже могут оказаться неподходящими.
    Другими словами лучше описывает ситуацию следующая картина.
    ab_2

    В итоге, полученное “дерево решений” получается довольно ветвистым, а его “построение” делается методом “разведки боем” и занимает уйму времени. При этом, когда человек уже находится в конечной точке B и если он не страдает потерей памяти, то скорее всего повторить этот путь ему будет намного проще. Он уже знает как добраться к цели, по каким именно дорогам идти и на каком перекрестке свернуть.

    Конечно более сложный случай, когда нет хороших проторенных “дорог”. Например, если это принципиально новая разработка. В таком случаях утверждение “Что он тут такого делает уже N-цатый год?“, звучит аналогично претензии к Колумбу: “Что тут такого? Здесь и ежу понятно, что нужно просто плыть на запад и попадешь в Америку“. Сегодня это кажется очевидным, а тогда найти средства на подобную авантюру было не так уж и просто.  Опять-таки в итоге Колумб все-таки ошибся где-то в три с половиной раза (почти на Пи), ведь изначально он хотел попасть в Индию, а она намного дальше…

    Возвращаясь в наши дни, к теме этой заметки, хотел подвести небольшое резюме.

    • Чтобы оценить сложность проекта нужно проделать большую работу (см. картинку с деревом решений). Не стоит прогибаться, когда заказчик требует выдать ему оценку сложности какого-то нового проекта в человеко-часах, суть которого вам изложили только что на словах в трех предложениях за чашечкой кофе. Реальная цена такой оценки наверное будет меньше стоимости выпитой вами чашки кофе.
    • Не стоит удивляться и сильно корить себя за количество потраченного времени. Во-первых в жизни часто сложности забываются, поэтому возникает кажущееся ощущение легкости пройденного пути, а во-вторых задним умом мы все гении.
    • Желательно искать хорошего “проводника”, у которого был опыт работы если не в аналогичных, то хотя бы в похожих проектах. Естественно, что каждый проект в чем-то уникален, но возможно его интуиция и опыт позволит частично избежать попадания в тупиковые ситуации.

    P.S. В качестве иллюстрации нарисовал дерево, на развилках которого выбирается один вариант и подсвечивается красным цветом. При нажатии мышкой на дерево, оно случайным образом перестраивается.
    Приятного просмотра!

    P.P.S. Дерево прорисовывается с помощью языка программирования processing. Собственно экспериментами с ним, а также arduino и raspberry pi сейчас посвящены воркшопы, которые мы проводим вместо проводимых ранее Scala-тусовок.