пятница, 27 июля 2012 г.

The Joda umbrella

Joda (http://joda.sourceforge.net/) - это группа java-проектов с открытым исходным кодом для расширения базовой функциональности jdk. В настоящее время включается в себя joda-money, joda-beans, joda-primitives, joda-convert и joda-time. Все библиотеки характеризуются узкой специализацией, небольшим размером, хорошим описанием и javadoc'ом, простотой и интуитивностью применения, совместимостью и удачным взаимодействием с jdk. Что же включает в себя эта группа и какие из них стОит поместить в свою "копилку" полезных библиотек?


Joda-Money - библиотека для работы с валютой. Фактически реализует основные и потому наиболее часто используемые операции (арифметические действия, конверсия, сравнение, форматирование), поддерживает ISO-4217. Совсем маленький пример представлен ниже.
package by.father.examples.jodatest;

import org.joda.money.CurrencyUnit;
import org.joda.money.Money;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class JodaMoneyTest {

    public static void main (String[] args) {
        CurrencyUnit rub = CurrencyUnit.of("RUB");

        Money moneyRub = Money.of(rub, 685);
        System.out.println(moneyRub);

        Money moneyJpy = Money.parse("JPY 350");
        System.out.println(moneyJpy);

        Money moneyUsd = Money.of(CurrencyUnit.USD, 15);
        BigDecimal exchangeRate = new BigDecimal(32);
        Money moneyUsdToRub = moneyUsd.convertedTo(rub, exchangeRate, RoundingMode.DOWN);
        System.out.println(moneyUsd.toString() + " equals to " + moneyUsdToRub
                + " (exchange rate is " + exchangeRate + ").");
    }

}
Joda-Beans - своего рода генератор, позволяющий по имеющемуся JavaBean (свойства которого помечены нужными аннотациями) автоматически сгенерировать get/set методы.

Joda-Primitives - обычно мы работаем с примитивными типами (int, long и пр.) и только при необходимости обращаемся к классам-оболочкам (Integer, Long и пр.). Один из примеров, когда такая ситуация возникает - использование коллекций: в java есть List<Integer>, но не List<int>. Joda-Primitives решает эту ситуацию, предоставляя возможность работать с коллекциями примитивов. Примитивная коллекция использует меньше памяти, работает быстрее и экономит на сборке мусора.

Joda-Convert - десяток классов для упрощения преобразования "строка - класс" и "класс - строка". Варианта использования два.
1) Использование org.joda.convert-аннотаций для того, чтобы указать конвертеру на методы преобразований.
package by.father.examples.jodatest;

import org.joda.convert.FromString;
import org.joda.convert.ToString;

@SuppressWarnings("unused")
public class JodaConverterTestClassAnno {

    String value;

    public JodaConverterTestClassAnno (String value) {
        this.value = value;
    }

    /**
     * The method 'object - string' is declared with annotation 'org.joda.convert.ToString'
     * and is accessible everywhere though global instance StringConvert.INSTANCE.
     * @return object that was converted to string.
     */
    @ToString
    @Override
    public String toString () {
        System.out.println("Class is converting to String with " + value);
        return value;
    }

    /**
     * The method 'string - object' is declared with annotation 'org.joda.convert.ToString'
     * and is accessible everywhere though global instance StringConvert.INSTANCE.
     * @param value string that was parsed into object.
     * @return object.
     */
    @FromString
    public static JodaConverterTestClassAnno parseAnno (String value) {
        System.out.println("New class JodaConverterTestClassAnno is creating with " + value);
        return new JodaConverterTestClassAnno(value);
    }

}
Проверяем:
    private void testAnno () {
        // Test using global instance StringConvert.INSTANCE.
        JodaConverterTestClassAnno jctc = StringConvert.INSTANCE.convertFromString(
                        JodaConverterTestClassAnno.class, "'through annotated method'");
        StringConvert.INSTANCE.convertToString(jctc);
    }
2) Регистрация произвольных методов в качестве преобразователей. Расширить глобальный инстанс нельзя, поэтому придётся создавать свой и регистрировать методы там.
package by.father.examples.jodatest;

import org.joda.convert.StringConvert;

@SuppressWarnings("unused")
public class JodaConverterTestClassReg {

    // special converter for this class
    private static StringConvert specialConverter = null;
    String value;

    public JodaConverterTestClassReg (String value) {
        this.value = value;
    }

    /**
     * Allow other classes to get this special converter. You can use any way for that; here i'm using a simple kind of
     * singleton.
     * @return created converter.
     */
    public static StringConvert getSpecialConverter () {
        if (specialConverter == null) {
            // create special converter and register methods
            specialConverter = new StringConvert(true);
            specialConverter.registerMethods(JodaConverterTestClassReg.class, "toString", "parse");
        }
        return specialConverter;
    }

    /**
     * The method 'object - string' is registered in special converter.
     * @return object that was converted to string.
     */
    @Override
    public String toString () {
        System.out.println("Class is converting to String with " + value);
        return value;
    }

    /**
     * The method 'string - object' is registered in special converter.
     * @param value string that was parsed into object.
     * @return object.
     */
    public static JodaConverterTestClassReg parse (String value) {
        System.out.println("New class JodaConverterTestClassReg is creating with " + value);
        return new JodaConverterTestClassReg(value);
    }

}
Проверяем:
    private void testReg () {
        // Test using methods registered in special converter
        StringConvert specialConverter = JodaConverterTestClassReg.getSpecialConverter();
        JodaConverterTestClassReg jctc = specialConverter.convertFromString(
                        JodaConverterTestClassReg.class, "'through special registered converter'");
        specialConverter.convertToString(jctc);
    }
Казалось бы, задача простая и банальная - сделать удобным преобразования объектов в строку и парсинг строк в объекты. И реализовать её может любой разработчик нужным ему способом. С этой т.зр. эта библиотека неинтересна.
Вместе с тем, зачем писать заново то, что уже написано? С этой т.зр. можно поставить для себя галочку в строке "делать преобразование String-object-String" только через joda-convert, и использовать этот функционал в своих проектах.
Пост в блоге автора Stephen Colebourne's Weblog о выпуске библиотеки

И наконец, the last but not the least Joda-Time - наиболее известная и активно поддерживаемая/используемая библиотека проекта. Как гордо говорится на странице, это "де-факто стандартная библиотека для работы с датами и временем в java". Реализация как Date, так и Calendar в java core имеют серьёзные недостатки, из-за чего joda-time и стала такой популярной. В качестве подтверждения популярности и качества библиотеки можно рассматривать предложения о включении joda-time в состав jdk 7 (правда, эти ожидания так и не оправдались, зато появились новые - о включении в jdk 8).

Т. о., the joda umbrella - группа из 5-ти (в настоящее время) проектов, направленных на облегчение и упрощение для разработчика определённых действий. Строго imho, три из них - joda-beans, joda-primitives и joda-convert - имеют не особенно большую ценность; joda-money будет действительно полезна для работы с валютами, а вот joda-time - наиболее интересный и востребованный продукт (а потому ему посвящён отдельный пост http://itech-notes.blogspot.com/2012/08/joda-time.html).

Комментариев нет:

Отправить комментарий