На информационном ресурсе применяются рекомендательные технологии (информационные технологии предоставления информации на основе сбора, систематизации и анализа сведений, относящихся к предпочтениям пользователей сети "Интернет", находящихся на территории Российской Федерации)

Практически Groovy : Функциональное программирование с помощью использованием замыканий и карринга. Часть 5

Бизнес-правила под соусом карри

Все эти кулинарные разговоры о кухне замыканий – это хорошо, но более бизнес-ориентированным читателям понравится следующий пример. Рассмотрим задачу расчета "чистой" цены определенной позиции Book, учитывая скидку магазина и различные государственные налоги, например, налог на добавленную стоимость. Если вы включите эту логику в состав класса Book, получившееся решение, вероятно, будет жестким. Если, например, магазин может изменить значение скидки, или захотеть применять ее только к некоторым позициям, то такое решение будет недостаточно гибким.

И как же быть? С помощью замыканий и карринга можно без труда приспособиться к изменению бизнес-правил. Вы можете использовать набор простых замыканий, представляющих отдельные бизнес-правила, и комбинировать их различными способами с помощью композиций. И, наконец, вы можете сопоставлять их с коллекциями с помощью шаблонов вычислений.

В листинге 8 показан пример книжного магазина. Замыкание rMultiply представляет собой частичное приложение, которое преобразует бинарное умножение в унарное замыкание, используя постоянный второй операнд. Два замыкания calcDiscountedPrice и calcTax являются экземплярами замыкания rMultiply с фиксированными значениями множителя. Замыкание calcNetPrice представляет собой алгоритм расчета "чистой" цены, сначала умножающий цену на скидку, а затем - на налог на с продаж. И, наконец, к цене книги применяется calcNetPrice.


Листинг 8. Бизнес-объект книги

import fp.*

class Book {
@Property name
@Property author
@Property price
@Property category
}

def bk = new Book(name : 'Groovy', author :
'KenB', price : 25, category : 'CompSci')
// постоянные
def discountRate = 0.1
def taxRate = 0.17
// замыкание книги
def calcDiscountedPrice = Functor.rMultiply.curry(1 - discountRate)
def calcTax = Functor.rMultiply.curry(1 + taxRate)
def calcNetPrice =
Functor.composition.curry(calcTax, calcDiscountedPrice)
// расчет чистой цены
def netPrice = calcNetPrice(bk.price)
println "netPrice: ${netPrice}" // netPrice: 26.325
наверх