Статьи

Языковая конструкция против шаблона проектирования — PHP массивы в Java

Автоматическая миграция является сложной задачей по многим причинам. Одним из них является необходимость обеспечения хорошего качества кода для сгенерированного кода. В частности, переход с PHP на Java еще сложнее, так как языки сильно различаются с точки зрения моделей исполнения (интерпретируемых и динамических), систем типов (свободно-динамических и строго-статических) и так далее.

Проблема с массивами PHP

Особой проблемой является использование ассоциативных массивов PHP для построения структур данных, даже если классы были бы лучшим выбором. Для построения массивов PHP предоставляет специальную языковую конструкцию, позволяющую следующее:

$a = array("entry1",
"key2" => "entry2",
array("key31", "nested entry"));

Библиотека времени выполнения NTILE PHP предоставляет Arrayи ArrayEntryклассы для эмуляции этой концепции. Однако, если идти традиционным путем, сгенерированный код может выглядеть слишком сложным в сравнении:

a = new Array(new ArrayEntry("entry1"),
new ArrayEntry("key2", "entry2"),
new ArrayEntry(
new Array(
new ArrayEntry("key31",
"nested entry" ));

Есть много вещей, с которыми нужно иметь дело при создании программного мигратора с PHP на Java, так что улучшение этого не было таким уж высоким в нашем списке приоритетов. Но потом мы вспомнили шаблон флюидных интерфейсов , который мы уже использовали с библиотекой Apache Commons Lang .

Дизайнерский узор на подхвате

В Java переопределяется Object.equals (Object) для правильной проверки равенства объектов и метода Object.hashCode () при размещении объектов в хеш-таблицах. Кодировать их вручную утомительно, а классы Commons Lang EqualsBuilder и HashCodeBuilder упрощают процесс, как в этом случае:

new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(field1, rhs.field1)
.append(field2, rhs.field2)
.isEquals()

Как следствие, мы определили ArrayBuilderкласс со следующей подписью:

public class ArrayBuilder<V> {
public ArrayBuilder() { }
public ArrayBuilder<V> put(Object key, V value) { }
public ArrayBuilder<V> put(V value) { }
public Array<V> getArray() { }
}

Использование ArrayBuilderдля переноса кода PHP, представленного выше, просто:

a = new ArrayBuilder<Object>()
.put("entry1")
.put("key2", "entry2")
.put(new ArrayBuilder<String>()
.put("key31", "entry3")
)
.getArray();

Хотя приведенный выше код все еще немного сложнее, чем код на PHP, он предоставляет преимущества обобщенных типов. Таким образом, легко увидеть, что массив должен содержать все виды данных, следовательно, универсальный параметр Object. А также, что массив из третьей записи всегда будет содержать строки. Эта информация также облегчит переход к объектно-ориентированным структурам данных по мере развития приложения.

Выводы

Трудно поддерживать простоту языка программирования, потому что возникает соблазн добавить новые конструкции, облегчающие определенные задачи. Мы видим, как это происходит со всеми разговорами о JSR, которые должны стать частью спецификации языка Java 7. Это особенно верно для функции поддержки XML на уровне языка .

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