Groovy : Затваряния или методи

Имам навика да използвам Closures навсякъде, където мога, вместо обикновени методи, дори когато нямам нужда от достъп до безплатни променливи. И така, ще използвам това:

def addNumbers = { left, right -> left + right }

.. вместо това:

def addNumbers (left,right) { left + right }

Това лоша практика ли е? Предпочитам допълнителната мощност, която получавам, когато използвам затваряния пред методите, и много предпочитам синтаксиса.

Благодаря!


person djcredo    schedule 01.12.2009    source източник
comment
Само не забравяйте, че не можете лесно да посочите типа връщане на затваряне. За методите е много по-лесно. Освен това затварянията не работят добре с @TypeChecked или @CompileStatic.   -  person Seagull    schedule 22.10.2014


Отговори (2)


Използвам затваряния само там, където имам нужда от тях, т.е. използвам методи по подразбиране. Правя това, защото

  • Методите са по-прости от затварянията. Затварянията имат делегат, собственик, запазват достъп до променливи, които са били в техния локален обхват, когато са създадени (това, което наричате „свободни променливи“). По подразбиране извикванията на метод в рамките на затваряне се разрешават от:

    1. Closure itself
    2. Собственик на затваряне
    3. Делегат за затваряне

Но този ред може да бъде променен по време на изпълнение и делегатът на затваряне може също да бъде променен на всеки обект.

Всички тези фактори комбинирани могат да направят код, който използва затваряния, много труден за грок, така че ако не се нуждаете от тази сложност, предпочитам да я елиминирам, като вместо това използвам метод

  • Генерира се .class файл за всяко затваряне, дефинирано в Groovy. Имам точно нула доказателства в подкрепа на твърдението, че обикновеният метод е по-ефективен от затварянето, но имам подозрения. Най-малкото, много класове може да ви накарат да изчерпите пространството в паметта на PermGen - това ми се случваше често, докато не увеличих пространството си на PermGen до около 200MB

Нямам представа дали практиката, която препоръчвам (използване на методи по подразбиране и затваряне само когато имате нужда от тях) се счита широко за „най-добра практика“, така че съм любопитен да чуя какво мислят другите.

person Dónal    schedule 01.12.2009

Въпреки че всички неща, които @Don казва, са верни, не знам някое от тях да е толкова значимо. Можете да замените делегата на затваряне, което може да промени изпълнението, но освен ако не предавате затварянето наоколо (което така или иначе не можете да направите с метод), всъщност не е нужно да се притеснявате, че някое от тези неща ще се случи. Играта с делегата е функция, а не задължение.

Що се отнася до възможен удар на производителността от файлове с допълнителни класове, защо използвате Groovy, ако толкова се притеснявате за производителността?

Моето мнение е, че няма особено значение. Ако имате много хора в екипа си, които са стари Java разработчици, те вероятно няма да харесат, когато използвате затваряния там, където методът е подходящ. От друга страна, някой, който владее Groovy, ще се подразни, ако претрупате всичко с методи, когато затварянето има повече смисъл.

tl;dr - Няма твърдо и бързо правило, вместо това трябва да упражнявате добра преценка с поглед към четливостта на кода.

person noah    schedule 28.12.2009
comment
Напълно съм съгласен, че моите точки са сравнително незначителни, а сбитостта е много по-важно съображение. - person Dónal; 12.09.2011
comment
В зависимост от употребата, прекомерната употреба на затваряния може да доведе до значително влошаване на производителността и паметта, поради евентуално неиздадени java.lang.ref.SoftReference екземпляри. В обикновените скриптове и класове това няма да е проблем, но в някои конкретни случаи (напр. огромни XML файлове за работа с MarkupBuilder) трябва да избягвате използването на затваряния. - person Tiago Fernandez; 12.09.2011
comment
Като цяло предпочитам добрия стил пред преждевременната оптимизация. Винаги е добра идея да профилирате кода си от време на време и това ще ви помогне да идентифицирате възможности за оптимизиране. Разбира се, всяко ново издание на Groovy (и JDK по същия начин) може да донесе нов набор от оптимизации, така че оптимизирането на вашия код трябва да се извършва на база цена/полза. В крайна сметка: напишете възможно най-четливия, интуитивен код и не губете време за оптимизиране на нещо, което вероятно ще бъде оптимизирано за вас. - person ngreen; 27.01.2014