Tuesday, December 27, 2011

Читая Practical Clojure


Объектно-ориентированный подход несомненно лучше процедурного, однако не лишен недостатков. Цитата из Practical Clojure:

For the last decade, at least, the object-oriented style has dominated computer programming through its promises of data abstraction, code reuse, encapsulation, and modularity. It has delivered on these with varying levels of success, and is no doubt an improvement over the sequential or procedural styles that preceded it. But a number of problems have also become apparent:
  • An object’s mutable state is unmanageable and dangerous in a highly concurrent environment.
  • It doesn't really solve the problems of code abstraction and modularization. It is just as easy to write over-dependent “spaghetti” code in an object-oriented language as any other. It still takes skill and special effort to write code that can truly be used without problems in a variety of environments.
  • Inheritance is fragile and can be dangerous. Increasingly, even experts in object- oriented languages are discouraging its use.
  • It encourages a high degree of ceremony and code bloat. Simple functionality in Java can require several interdependent classes. Efforts to reduce close coupling through techniques like dependency injection involve even more unnecessary interfaces, configuration files, and code generation. Most of the bulk of a program is not actual program code, but defining elaborate structures to support it. 

Monday, October 24, 2011

Hadoop Day at Dev Time

25 октября состоится Hadoop Day в рамках Dev Time, где я буду выступать с докладом о Apache Zookeeper

Friday, May 27, 2011

QA-Club

Вчера прошел мой доклад в рамках QA-club. Спасибо организаторам за предоставленную возможность выступить. Итак все материалы по докладу:

Презентация

Пример
Для работы проекта необходима подтянуть следующие библиотеки ScalaMate (позволяет использовать dependency injection в scala test), webelement-wrappers (позволяет убодно работать с html элементами).

Ссылки для дальнейшего ознакомления
BDD:

Dependency Injection:
Рекомендую посмотреть видео

Code Review
Удобная система для Code Review rietveld
Видео от разработчика

DVCS

Saturday, May 14, 2011

To GWT or not to GWT

Прошло время, когда web-разработка заключалась в обработке HTTP запросов и рендеринге соответсвующей html странички. Сейчас, куда не плюнь, везде требуется Rich UI. У java разработчика есть выбор: либо писать rich ui на javascript'e, либо воспользоватся GWT платформой, и писать на родимой жаве.

В последнее время мне удалось поработать с GWT, итак за и против.

За GWT:

1. Не нужно учить javascript. Если вы гуру и не одну собаку съели педаля на жабе и принципиально не хотите учить javascript, то gwt в самый раз.

2. Все приимущества java. Статическая типизация, IDE, дебаггер, рефакторинги, анализаторы кода -- все к вашим услугам.

3. Один код на сервере и на клиенте. Код написанный для сервера может быть скомпилирован в javascript и работать на клиенте.

4. Google. GWT разрабатывается, не командой волосатых программистов из гаража, а корпорацией google и используется в проектах компании.

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

Против GWT:

1. Java == No fun. Писать на жаве UI неудобно. Количество строк кода в результате -- огромно.

2. Медленно. Скорость разработки на GWT на порядок меньше чем с помощью javascript'a. В большинстве из-за количества кода, которое приходится писать. Скорость работы GWT-овского компилятора уничтожает желание использовать GWT.

3. Отсутсвие подходов к написанию программ с помощью GWT. Best practices и подходы по написанию программ с помощью GWT постоянно меняются. RequestFactory и Activity Framework до сих пор сырые.

Wednesday, May 11, 2011

ZooKeeper Intro

Любое распределенное приложение не может обойтись без центрального сервиса, который координирует процессы в нем. Реализовывать координацию можно, однако разработка отказоустйчивой системы координации без deadlock'ов и race conditions -- задача не из тревиальных. Проект Apache ZooKeeper призван избавить нас от решения этой проблемы.

ZooKeeper -- это распределенный, open-source сервис координнации для расспределенных приложений. Он предоставляет низкоуровневый API, с помощью которого приложения могут реализовать высокоуровневые сервисы для координации и синхронизации процессов в расспредеелнной системе.

API ZooKeeper'a черезвычайно прост. Распределенные процессы могут координироваться между собой с помощью расшаренной на всех клиентов иерархии znode'ов, организация которых по структуре похожа на файловую систему. Как и в файловой системе каждый znode идентифицируется своим уникальным путем, вида /node1/stuff/logs. В отличии от привычной файловой системы, каждый znode может быть корневым узлом для других znode'ов. Если говорить в терминах файловой системы: файл может выступать в роли директории. Znode'ы версионируются и ZooKeeper позволяет "смотреть"(watch) за изменениями в ноде. Как только znode'a изменяется, клиент, смотрящий за нодой, получает пакет, который говорит что в ноде произошло измение.


ZooKeeper
 реплицируемый и обрабатывает команды в строгой последовательности. Первое намного повышает его надежность, второе дает возможность пользователям разрабатывать примитивы синхронизации для распределенных систем. Все данные ZooKeeper держит в памяти, что позволяет ему работать черезвычайно быстро. Разработчики дауют нам следующие гарантии:
  • Sequential Consistency - Обновления от клиента будут применены в порядке в котором они были отправены
  • Atomicity - Изменения от клиента атомарны, они либо исполняются либо нет
  • Single System Image - Клиент получет одинаковый набор znode'ов вне зависимости от того к какому серверу он подключен
  • Reliability - Как только измение было применено, состояние будет неизменно до тех пор пока клиент не перетрет его
  • Timeliness - Состояние системы для клиент гарантированно up-to-date с некоторой погрешностью по времени

Wednesday, May 4, 2011

Почему Scala?

Выразительный синтаксис

Скала позволяет писать код без избыточных символов и дает возможность создавать DSL-подобный код:
  • Необязательно ставить точки с запятой в конце строки
  • object.doSomething() равнозначен object doSomething()
  • Инфиксные операторы
Поддержка функционального программирования

Scala предоставляет мощь объектно-ориентированного программирования, добавляя к нему изящные подходы из функционального
  • Поддержка функций высокого порядка
  • Поддержка замыканий

Улучшенное ООП

Скала добовляет поддерживает ОО парадигму Java-мира, расширяя ее систему типов
  • Trait (mixin) -- интерфейсы, которые могут включать логику и позволяют реализовать множественное наследованиеBulleted List
  • Case классы для быстрого создания value object'ов. В скале можно не писать getter'ов, setter'ов, equals и hashCode
  • Duck typing со статической типизацией

Sunday, April 3, 2011

Не бойтесть автомаизировать

Использование автоматизированных тестов на selenium в качестве приемочных тестов становится распространненой тенденцией в индустрии разработки программного обеспечения. Об этом свидельствует успех прошедшей недавно конференции Selenium Camp, на которой Ваш покорный слуга выступал докладчиком. Отчасти этому способствует активная пропоганда от agile сообщества, отчасти наличием success stories от гигантов индустрии, таких как, например, Google, который является главным конрибьютером в новую, вторую, версию селениума.

Однако, нужны ли нам автоматизированные тесты, если у нас в команде есть группа тестировщиков или QA-инженеров, способных обеспечить качество проекта на должном уровне? Я считаю, что автоматизированные тесты дополняют QA-инжеров, избавляя их от ненужной рутинной работы. Зачем тратить время на регрессию, если ее может сделать за тебя компьютер?

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

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

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

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

Wednesday, March 23, 2011

Новинки JUnit. Категории

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

Первый вопрос который стоит перед командой при написании автоматизированных тестов -- как мы будем запускать тесты? Точнее -- какой фреймворк для тестирования нам выбрать? Если мы программируем на Java, выбор не велик. JUnit или TestNG.

Помню, когда мы начинали заниматься функциональными тестами на нашем последнем проекте, мы долго решали что же выбрать. Победил TestNG. Легкость создания test suit'a, возможность группировать тесты и запускать их параллельно -- вот что определило наш выбор. В тот момент я подписался на интересные блоги и рассылки связанные с тестированием, и через некоторое время обнаружил, что JUnit активно развивается и догоняет TestNG по функциональности, при этом превосходит его в продуманности API.

Так, в JUnit начиная с версии 4.8 появился механизм для метки и группировки тестов, под названием Categories.
Процесс группировки тестов в JUnit до появления категорий можно стравнить с организацией писем в Microsoft Outlook. Мы можем группировать тест методы в классы, а классы в пакеты.
Теперь, с помощью категорий, группировка тестов похожа на группировку писем в GMail.

Представляются категории в виде java интерфейсов, что дает приемущества по сравнению с группами в TestNG. В отличии от строковых констант коими являются группы, мы можем переименовывать категории в IDE, плюс есть возможность построить йерархии категорий, что дает нам гибкость в организации тестов.

Предположим, что у нас есть 4 категории: SmokeTest говорит что наш тест - смоук тест, BrokenTest показывает, что тест тестирует поломанный функционал, а с помощью FastTest и SlowTest мы помечаем тесты по времени выполнения.

public interface SmokeTest {}

public interface BrokenTest {}

public interface FastTest {}

public interface SlowTest {}

Допустим у нас есть два тест класса с помеченными методами:

@Category(SmokeTest.class)
public class SomeSmokeTests {
@Test
@Category(FastTest.class)
public void someFastTest() {
// test something
}

@Test
@Category(SlowTest.class)
public void someReallySlowTest() {
// test something
}
}

public class SomeTestCase {

@Test
@Category({SmokeTest.class, FastTest.class})
public void fastSmokeTest() {
// test something
}

@Test
@Category({SmokeTest.class, FastTest.class, BrokenTest.class})
public void fastBrokenSmokeTest() {
// test something
}
@Test
@Category({SmokeTest.class, SlowTest.class})
public void slowSmokeTest() {
// test something
}

}

С помощью категорий мы можем построить test suite, который будет запускать быстрые smoke тесты с работающим функционалом:

@RunWith(Categories.class)
@IncludeCategory(SmokeTest.class, FastTest.class)
@ExcludeCategory(BrokenTest.class)
@SuiteClasses(SomeSmokeTests.class, SomeTestCase.class)
public class RunFastSmokeTestCases {}

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

К счастью эта проблема решается с помощью библиотеки junit-suite-configurator. Так выглядит конфигурация эта же конфигурация написанная с ее помощью:

@RunWith(Suite.Configuration.class)
public class Suite {

public static class Configuration extends AbstractConfiguration {

public Configuration(Class testClass) {
super(testClass);
}

@Override
protected void configure() {
run(classes(SomeSmokeTests.class, SomeTestCase.class))
.filter(includeCategories(SmokeTest.class, FastTest.class))
.filter(excludeCategories(BrokenTest.class))
.applyRule(new Rule1())
).invokeIn(singleThread());
}
}
}