Синтаксис языка SFig эффективен и понятен (и лучше, чем XML DSL Spring-Framework)? - PullRequest
0 голосов
/ 21 декабря 2008

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ:

Не приняли ответ на это как не было никаких отзывов от опытный Spring Framework Разработчики.

Я работал над заменой DSL для использования в файлах applicationContext.xml Spring-Framework (где описаны инициализация bean-компонента и зависимости для загрузки в фабрику bean-компонентов Spring).

Моя мотивация в том, что мне просто не нравится использование Spring для этой цели XML, и мне не нравятся какие-либо альтернативы, которые были разработаны до сих пор. По разным причинам, в которые я не буду вдаваться, я хочу остаться с декларативным языком, а не с каким-либо императивным языком сценариев, таким как Groovy.

Итак, я взял инструмент синтаксического анализа ANTLR и разрабатывал новый DSL фабрики бинов, который я назвал SFig. Вот ссылка, которая больше говорит об этом:

SFig ™ - альтернативный язык конфигурации метаданных для Spring-Framework

А вот и сайт репозитория исходного кода:

http://code.google.com/p/sfig/

Мне интересно узнать, как у меня дела с синтаксисом языка. Как вы думаете, SFig эффективен и понятен? (Меня сейчас особенно волнует многострочная текстовая строка):

properties_include "classpath:application.properties";


org.apache.commons.dbcp.BasicDataSource dataSource {
    @scope = singleton;
    @destroy-method = close;
    driverClassName = "${jdbc.driverClassName}";
    url = "${jdbc.url}";
    username = "${jdbc.username}";
    password = "${jdbc.password}";
    defaultAutoCommit = true;
}


org.springframework.orm.ibatis.SqlMapClientFactoryBean sqlMapClient {
    @scope = singleton;
    @init-method = afterPropertiesSet;
    @factory-method = getObject;
    configLocation = "classpath:sqlmap-config.xml";
    dataSource = $dataSource;
}


/* this string will have Java unescape encoding applied */
STRING str = "\tA test\u0020string with \\ escaped character encodings\r\n";


/* this string will remain literal - with escape characters remaining in place */
STRING regexp = @"(\$\{([a-zA-Z][a-zA-Z0-9._]*)\})";


/* multi-line text block - equates to a java.lang.String instance */
TEXT my_multi_line_text = ///
Here is a line of text.
This is yet another. Here is a blank line:

Now picks up again.
///;


/* forward use of 'props' bean */
java.util.HashMap map {
    this( $props );
}


/* equates to a java.util.Propertis instance */
PROPERTIES props {
    "James Ward" = "Adobe Flex evangelist";
    "Stu Stern" = "Gorilla Logic - Flex Monkey test automation";
    Dilbert = "character in popular comic strip of same title";
    "App Title Display" = "Application: ${app.name}";
    "${app.desc}" = "JFig processes text-format Java configuration data";
}


/* equates to a java.util.ArrayList instance */
LIST list {
    this( ["dusty", "moldy", "${app.version}", $str] );
    [234, 9798.76, -98, .05, "numbers", $props, ["red", "green", "blue"]];
}

Ответы [ 2 ]

0 голосов
/ 22 декабря 2008

Я расскажу немного о Spring и его файле applicationContext.xml, который внесет ясность в некоторые вещи, происходящие в синтаксисе SFig.

Файл applicationContext.xml используется для выражения инициализации bean-компонента для bean-компонентов, которые будут управляться фабрикой bean-компонентов Spring. Итак, учитывая пример bean-компонентов, которые я видел в моей SFig-версии этого файла, в коде Java-приложения можно было бы запросить фабрику bean-компонентов сделать экземпляр bean-компонента следующим образом:

SqlMapClient sqlMapClient = getBean("sqlMapClient");

Фабрика bean-компонентов заботится о любой реализации и инициализации, необходимых для bean-компонента, вплоть до внедрения зависимостей. В этом случае компоненту SqlMapClient требуется экземпляр компонента dataSource (который также описывается и упоминается в примере SFig).

Дескриптор бина передает следующую информацию фабрике бинов:

  • имя Java-класса bean-компонента
  • идентификатор компонента, по которому можно запросить или сослаться на него
  • мета-атрибуты определения бина (необязательно)
  • аргументы инициализации конструктора (необязательно)
  • и / или инициализаторы свойств

'@' ставит префикс мета-атрибутов определения компонента. Это атрибуты, которые используются фабрикой компонентов для управления компонентом. Например, @scope = singleton сообщит фабрике бинов о создании единственного экземпляра бина, кеширует его и раздаст ссылки на него при запросе. Те, которые могут быть установлены, те же, что определены в Spring-Framework.

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

Или bean-компонент можно инициализировать, задав его свойства. Идентификаторы, которые назначены и не имеют префикса '@', являются свойствами bean-компонента.

При ссылке на bean-компонент, который является обязательной зависимостью, на него можно сослаться с префиксом его идентификатора компонента с помощью $. Несколько примеров этого появляются в примере SFig.

Символьная переменная $ {foo.bar}, появляющаяся в строковых литералах, будет заменена значением свойства Java. В этом случае свойства загружаются из файла application.properties через эту строку:

properties_include "classpath:application.properties";

Свойства Java-системы будут рассматриваться следующим, если они не найдены ни в одном из включенных свойств Это широко применяемая практика во многих Java-фреймворках. В текущем XML-файле applicationContext.xml есть способ разрешить это использование.

Поскольку java.util.Properties часто используются для инициализации bean-компонентов, SFig предоставляет PROPERTIES в качестве специального удобного синтаксиса для объявления объекта Properties. Аналогично для java.util.List, который имеет соответствующий SFig LIST. Кроме того, массивы значений могут быть объявлены в квадратных скобках [...].

Дополнительно есть TEXT для объявления блоков многострочного текста. '@' - префикс строкового литерала означает отключение escape-кодирования - синтаксис языка заимствован из C #.

Одной из основных целей проектирования SFig DSL является сохранение декларативного характера. Я намеренно воздерживаюсь от добавления каких-либо обязательных функций сценариев. Сложность логики программирования, встроенной в текстовый файл конфигурации, предполагает возможность его отладки. Не хочу открывать еще одно измерение отладки кода.

0 голосов
/ 22 декабря 2008

У меня нет особого опыта работы с Spring XML, о котором вы говорите, поэтому вам следует взять следующую обратную связь с небольшим количеством соли.

В качестве второго и третьего предупреждения:

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

Более широкий, мета-вопрос: как DSL вы пытаетесь настроить Spring или как более общий класс фреймворков?

Там: будьте бдительны. Теперь мой субъективный и неполный отзыв;)

  • Я не уверен, что понимаю причину, по которой у вас есть префикс @ для scope и destroy-method, но не driverClassName. Кроме того, сочетание и xml-case, и camelCase не совсем очевидно для начала. Является ли префикс @ модификатором типа, или это ключевые слова на языке?

  • Я не совсем уверен в ваших намерениях насчет формата заголовка блока. У вас есть имя класса, затем функция этого класса; намерение указать, какой класс вы собираетесь использовать для конкретной функции?

* 1 035 *, например
sqlMapClient: org.springframework.orm.ibatis.SqlMapClientFactoryBean {
    # body.
}

или даже:

sqlMapClient {
    @class = org.springframework.orm.ibatis.SqlMapClientFactoryBean;
    # is there a sensible (perhaps built-in) default if this is missing?
}
  • Мне нравится подстановка переменных ; Я предполагаю, что значения будут получены из свойств системы?

  • Мне нравится возможность указывать строковые литералы (без экранирования), особенно для показанных вами регулярных выражений. Однако наличие многосимвольной цитаты или модификатора цитаты кажется немного чуждым. Я думаю, вы рассматривали одинарные кавычки (оболочка и Perl используют одинарные кавычки для буквенных строк).

  • С другой стороны, я думаю, что тройной слеш для многострочный TEXT - правильный подход, но два напоминают комментарии на языках стиля C. Python использует тройной " для этой цели. Некоторые идиомы оболочки имеют многострочное текстовое соглашение, которое я бы не копировал.

  • Мне очень нравится внешний вид свойств и расположение конфигурации, используя то, что похоже на URI-представление адресации . Если это URI, classpath://file.xml может быть более понятным. Однако у меня может быть не тот конец палки.

  • Мне также очень нравится понятие списка и литералов карты, которые у вас есть, хотя я не уверен, где:

    • this входит в это (я думаю, вызов конструктора Java)
    • почему некоторые типы пишутся с большой буквы, а другие нет. Могу ли я считать, что по умолчанию существует тип MAP, который вы можете использовать более конкретно, если хотите?
    • является ли Дилберт строковым литералом без кавычек?

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

Иди хорошо.

...