Статьи

Groovy Стиль кодирования

Я использую Groovy около 4 лет. Код, который я писал 3 года назад, сильно отличается от кода 1 года и от кода, который я пишу в эти дни. Почему это?

Несомненно, одна часть этого — то, что я становился все более и более знакомым с Groovy за эти годы, и Groovy становится все более сильным; такие функции, как @Delegate и особенно @Mixin, меняют способ написания кода.

Однако основные причины разные. Когда я начал использовать Groovy, я был Java-разработчиком. И именно поэтому в течение первых нескольких месяцев мой код больше походил на Java с замыканиями и необычными коллекционными литералами; Я считаю, что это так для многих разработчиков Groovy.

Затем я много занимался разработкой на Ruby, и это изменило мои привычки и стиль кодирования. Всего несколько примеров: в Ruby нет интерфейсов. Они просто не имеют никакого смысла в мире Ruby. Вы не указываете тип, когда определяете переменную в Ruby. Мы указываем def в groovy, если не хотим указывать точный тип переменной.

Сравните эти две части кода:

class SqlPersonRepository
...
def find_by_name name
...
end
...
end

class SqlPersonRepository {
...
def findByName(name){
...
}
...
}

Они практически идентичны. Какой код будет писать разработчик Java, когда он начнет использовать Groovy?

class SqlPersonRepository implements PersonRepository {
...
Person findByName(String name){
...
}
...
}

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

И я был смущен, смущен двумя разными культурами (Java и Ruby), и я долго не мог решить, какой стиль я предпочел. Чтобы упростить это для себя, я попытался формализовать это, чтобы найти несколько простых правил, на которые я всегда буду обращать внимание, когда не знаю, какой стиль следует использовать.

Прежде чем упоминать правила, я хотел бы написать о трех основных вещах, влияющих на то, как я пишу код на Groovy.

  1. Совместимость с Java. Довольно часто ваши классы Groovy должны расширять классы Java или реализовывать некоторые интерфейсы. Или классы Java должны использовать ваши классы Groovy. В обоих случаях у вас нет выбора, но везде используются типы и интерфейсы. Если вы этого не сделаете, ваш Java-код станет безобразным.

  2. Поддержка IDE. Для ребят из Ruby все очень просто, IDE не очень вам помогают. Даже RubyMine от JetBrains (!!) не так впечатляет. Напротив, Groovy IDE действительно потрясающие. В частности, поддержка Groovy в IDEA обеспечивает расширенное автозаполнение и рефакторинг. Когда у вас есть все эти функции, вы не хотите их терять, поэтому вы указываете типы для автозаполнения.

  3. Использование динамических возможностей. Хотя Groovy обладает чрезвычайно мощными динамическими возможностями, позволяющими делать все (возможно, почти все) сумасшедшие вещи, которые я делал в Ruby, я не часто использую все эти возможности. Это просто не часть Groovy культуры. Если вы пишете даже небольшую библиотеку на Ruby, то обычно добавляете некоторые методы в базовые классы. Мы не делаем это в Groovy. За исключением Грааля и еще нескольких библиотек. Конечно, ситуация отличается при разработке языка, специфичного для предметной области. Но давайте будем честными, мы не делаем это каждый день.

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

Правило 1

Все, что является публичным, должно иметь указанный тип, если только тип не Object. Это значит, что я напишу публичный метод так:

Person findByName(String name){
...
}

Если аргумент или тип возвращаемого значения — Object, я ничего не указываю:

def transformObject(obj){
...
}

Правило 2

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

Person findByName(String name){
internalMethod name
}

private internalMethod(name){
...
}

Почему я это делаю? Лично для меня указание типов во всех частных методах добавляет много шума в код. Если у вас есть 50-строчный класс, все ясно из контекста. Вам не нужно повторяться все время.

Person findByName(String name){
def prefixedName = getFirstName(name)
}

private getFirstName(name){
...
}

Понятно, что name — это String, а тип возвращаемого значения — String. Зачем мне это писать?

Правило 3

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

class Person {
String name
int age
}

Правило 4

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

def greeting = sayHi('john')

private sayHi(name){
"Hi $name"
}

IDEA знает, что приветствие — GString.

Правило 5

Если что-то может быть сделано во время компиляции, это должно быть сделано во время компиляции. Если мне нужно делегировать вызовы методов другому объекту, я бы предпочел использовать @Delegatethan methodMissing.

Правило 6

Используйте интерфейсы для публичных API. Другим разработчикам гораздо проще понять, что необходимо реализовать, если используются интерфейсы. Если вам требуется что-то вроде:

class ConditionBuilder {
void addCondition(condition)
}

это может занять некоторое время, чтобы понять, что такое состояние.

Правило 7

Предоставить конструкторы для открытых классов.

class Person {
String name
int age

Person(String name, int age){
...
}
}

Очень часто я не предоставляю конструкторы для своих внутренних служебных классов. Вы могли бы сказать, что контакт строительства не ясен в этом случае. Лично для меня новый Person (имя: «Джон», возраст: 50) выглядит лучше, чем новый Person («Джон», 50), и обычно мой внутренний код тестируется очень хорошо, поэтому у меня нет проблем с нулевыми значениями.

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

 

С http://vsavkin.tumblr.com/post/3191162772/groovy-coding-style