Groovy: Закрытие или методы
У меня есть привычка использовать Closures везде, где я могу вместо обычных методов, даже если мне не нужен доступ к свободным переменным. Итак, я буду использовать это:
def addNumbers = { left, right -> left + right }
.. вместо этого:
def addNumbers (left,right) { left + right }
Это плохая практика? Я предпочитаю дополнительную мощность, которую я получаю при использовании замыканий по методам, и я предпочитаю синтаксис.
Спасибо!
Ответы
Ответ 1
Я использую только те блокировки, в которых они мне нужны, т.е. я использую методы по умолчанию. Я делаю это, потому что
-
Методы проще, чем закрытие. Закрытие имеет делегат, владелец, сохраняет доступ к переменным, которые были в их локальной области при создании (то, что вы называете "свободными переменными" ). По умолчанию вызовы метода в пределах замыкания разрешаются с помощью:
- Закрытие себя
- Закрытие владельца
- Закрытие делегата
Но этот порядок может быть изменен во время выполнения, а делегат закрытия также может быть изменен на любой объект.
Все эти факторы в совокупности могут сделать некоторый код, который использует закрытие очень сложно, но если вам не нужна такая сложность, я предпочитаю исключить его, используя вместо этого метод
- Файл .class создается для каждого закрытия, определенного в Groovy. У меня есть ровно нулевые доказательства, подтверждающие утверждение о том, что обычный метод более эффективен, чем закрытие, но у меня есть подозрения. По крайней мере, многие классы могут привести к тому, что вы исчерпаете пространство памяти PermGen - это часто случалось со мной, пока я не увеличил пространство PermGen до 200 МБ.
Я не знаю, является ли практика, которую я защищаю (использовать методы по умолчанию и закрывать только тогда, когда вы в них нуждаетесь) широко считается "лучшей практикой", поэтому мне любопытно узнать, что думают другие.
Ответ 2
В то время как все, что @Don говорит, истинны, я не знаю, что любой из них является настолько значительным. Вы можете переопределить делегат закрытия, который может изменить выполнение, но если вы не пропустите закрытие вокруг (которое вы не можете сделать с помощью метода в любом случае), вам действительно не нужно беспокоиться ни о какой из этих вещей. Игра с делегатом - это функция, а не ответственность.
Что касается возможной производительности, вызванной дополнительными файлами классов, почему вы используете Groovy, если вы беспокоитесь о производительности?
Мое мнение таково, что это не имеет большого значения. Если в вашей команде много людей, которые являются старыми разработчиками Java, они, вероятно, будут не нравиться, когда вы используете закрытие, где будет работать метод. С другой стороны, кто-то, свободно владеющий Groovy, будет раздражаться, если вы загромождаете все методы, когда закрытие имеет больше смысла.
tl; dr - нет жесткого и быстрого правила, вместо этого вы должны проявлять здравый смысл с прицелом на читаемость кода.