![Page 1: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/1.jpg)
ВИКТОР ПОЛИЩУК
JBoss Drools Expert
![Page 2: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/2.jpg)
Виктор Полищук
10+ лет коммерческой разработки
8+ лет работы с Java
3+ лет программирования на Drools
Участвовал/видел 50+ «проблемных» (из-за высокой нагружености логикой) проектов
0 из 9 «провальных» проектов на Drools
Технический лидер в Infopulse, Ukraine
Контрактор в BICS, Belgium
![Page 3: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/3.jpg)
«Простой» «Хитрый»
2.00
за SMS
0.00
за первые 10 SMS/день
1.50
за SMS внутри сети
2.50
за SMS
JokerMobile™
![Page 4: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/4.jpg)
Модель Данных: Customer
public class Customer {
String number;
Tariff tariff;
}
![Page 5: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/5.jpg)
Модель Данных: SMS
public class Sms {
String sender;
String receiver;
DateTime sent;
}
![Page 6: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/6.jpg)
Модель Данных: BillingRecord
public class BillingRecord {
Customer customer;
BigDecimal price;
Sms sms;
}
![Page 7: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/7.jpg)
Java FTW
Пишем God класс
Делим логику на стратегии по тарифам
Делим логику на атомарные стратегии
Что-то еще
![Page 8: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/8.jpg)
API
public interface TariffStrategy {
Collection<BillingRecord> calculate(
Customer customer,
Interval interval
);
}
![Page 9: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/9.jpg)
«Хитрая» Стратегия: стр. 1
Collection<Sms> messages = dao.findBySender(customer.getNumber(), interval); Collection<SmsBillingRecord> records = new ArrayList<SmsBillingRecord>(); Map<DateTime, List<Sms>> dailyMap = new HashMap<DateTime, List<Sms>>(); for (Sms sms : messages) { DateTime date = sms.getSent().withMillisOfDay(0); List<Sms> collection = dailyMap.get(date); if (collection == null) { collection = new ArrayList<Sms>(); dailyMap.put(date, collection); } collection.add(sms); }
![Page 10: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/10.jpg)
«Хитрая» Стратегия: стр. 2
for (List<Sms> value : dailyMap.values()) { Collections.sort(value, SMSComparator.INSTANCE); for (int i = 0; i < value.size(); i++) { Sms sms = value.get(i); if (i < 10) { records.add(new BillingRecord(customer, BigDecimal.ZERO, sms)); } else if (dao.findByNumber(sms.getReceiver()) != null) { records.add(new BillingRecord(customer, new BigDecimal("1.5"), sms)); } else { records.add(new BillingRecord(customer, new BigDecimal("2.5"), sms)); } } } return records;
![Page 11: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/11.jpg)
ПРАЗДНИК
Полный Успех
![Page 12: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/12.jpg)
Бонус
Может быть применен к любому тарифу
Могут складываться друг с другом
Правила наложения могут быть уникальны
![Page 13: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/13.jpg)
Модель Данных: Customer+
public class Customer {
String number;
Tariff tariff;
Collection<Bonus> bonuses;
}
![Page 14: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/14.jpg)
Бонус: «Двадцать»
Платеж 100.00 в месяц
Скидка 20% на все SMS
![Page 15: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/15.jpg)
Модель Данных: BillingRecord+
public abstract class BillingRecord { Customer customer; BigDecimal price; } public class SmsBillingRecord extends BillingRecord { Sms sms; } public class FixedBillingRecord extends BillingRecord { }
![Page 16: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/16.jpg)
Java FTW
Растим God класс
Пишем все в стратегии
Выносим цены в некий PriceManager
Создаем слой модифицирующий BillingRecord
Что-то еще
![Page 17: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/17.jpg)
БЕСПОКОЙСТВО
Частичный Успех
![Page 18: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/18.jpg)
Бонус: «Два по Пятьдесят»
После порога в 50 SMS в день:
Удваиваем количество бесплатных SMS
Скидка 50% на последующие SMS до конца дня
![Page 19: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/19.jpg)
Java WTF
Убиваемся о God класс
Меняем PriceManager
Добавляем LimitManager
Меняем «модифицирующий» слой: Передаем доп.информацию про стратегии и бонусы
Усложняем логику
Начинаем сначала
Что-то еще
![Page 20: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/20.jpg)
ДЕПРЕССИЯ... НЕНАВИСТЬ... РАЗДРАЖЕНИЕ... МИЗАНТРОПИЯ... ЗАМКНУТОСТЬ...
УСТАЛОСТЬ... АПАТИЯ...
Я Сделал Все Что Мог
![Page 21: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/21.jpg)
Drools Expert
Продукционная экспертная система
Построена на базе «Rete-сети»
Отличная документация
Открытый код
Бесплатная
Поддерживается JBoss
![Page 22: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/22.jpg)
Глоссарий
Working Memory
Rule Engine
Knowledge Base
Fact Fact Fact
Rule Rule Rule
![Page 23: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/23.jpg)
Базовый Синтаксис
rule “<Имя правила>”
<опции>
when
<условие или LHS>
then
<следствие или RHS>
end
![Page 24: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/24.jpg)
Drools: Тариф «Простой»
rule “Billing: charge -Simple-”
when
$customer : Customer(tariff==Tariff.SIMPLE)
Charge($sms : sms, customer==$customer)
then
log.info(“Charge {} as {}”, $sms, 2.0);
insertLogical(
new SmsBillingRecord($customer,2.0,$sms)
);
end
![Page 25: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/25.jpg)
Charge?
public class Charge {
Customer customer;
Sms sms;
}
<или>
declare Charge
customer : Customer @key
sms : Sms @key
end
![Page 26: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/26.jpg)
Drools: А Кто Платить Будет!?…
rule “Default: sender is in charge” when $period : Interval() $sms : Sms($sender : sender, $period.contains(sent)) $customer : Customer(number==$sender) not Charge(customer!=$customer, sms==$sms) then log.info(“Mark {} as regular”, $sms); insertLogical(new Charge($customer, $sms)); end
![Page 27: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/27.jpg)
Drools: Тариф «Хитрый» стр. 1
rule “Tariff -Smart-: free SMS” when Day($period : interval) $customer : Customer(tariff==Tariff.SMART) Charge($sms : sms, customer==$customer, $period.contains(sms.sent)) accumulate($c : Charge(customer==$customer, $period.contains(sms.sent), !sms.sent.isAfter($sms.sent)); $count : count( $c ); $count<=10) then log.info(“Mark {} as free”, $sms); insertLogical(new ChargeAsFree($customer, $sms)); end
![Page 28: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/28.jpg)
Drools : Тариф «Хитрый» стр. 2
rule “Tariff -Smart-: local SMS” when Day($period : interval) $customer : Customer(tariff==Tariff.SMART) Charge($sms : sms, customer==$customer, $period.contains(sms.sent)) not ChargeAsFree(customer==$customer, sms==$sms) exists Customer(number==$sms.receiver) then log.info(“Mark {} as local”, $sms); insertLogical(new ChargeAsLocal($customer, $sms)); end
![Page 29: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/29.jpg)
Drools: Тариф «Хитрый» стр. 3
rule “Billing: free of charge” when $customer : Customer() ChargeAsFree($sms : sms, $customer==customer) then log.info(“Charge {} as {}”, $sms, 0.0); insertLogical( new SmsBillingRecord($customer, 0.0, $sms) ); end
![Page 30: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/30.jpg)
Drools: Тариф «Хитрый» стр. 4
rule “Billing: charge local in –Smart-” when $customer : Customer(tariff==Tariff.SMART) ChargeAsLocal($sms : sms, customer==$customer) not ChargeAsFree(sms==$sms) then log.info(“Charge {} as {}”, $sms, 1.5); insertLogical( new SmsBillingRecord($customer, 1.5, $sms) ); end
![Page 31: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/31.jpg)
Drools: Тариф «Хитрый» стр. 5
rule “Billing: charge others in –Smart-” when $customer : Customer(tariff==Tariff.SMART) Charge($sms : sms, customer==$customer) not ChargeAsFree(sms==$sms) not ChargeAsLocal(sms==$sms) then log.info(“Charge {} as {}”, $sms, 2.5); insertLogical( new SmsBillingRecord($customer, 2.5, $sms) ); end
![Page 32: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/32.jpg)
Drools: Бонус «Двадцать»
rule “Subscription -20%-: refund” when $customer : Customer(bonuses contains Bonus.TWENTY) Charge($sms : sms, customer==$customer) not ChargeAsFree(sms==$sms) not Modifier(sms==$sms, modifier<0.8) then log.info(“Add modifier {} to {}”, 0.8, $sms); insertLogical(new Modifier($sms, 0.8)); end
![Page 33: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/33.jpg)
Drools: Тариф «Хитрый» стр. 4+
rule “Billing: charge local in –Smart-” when $customer : Customer(tariff==Tariff.SMART) ChargeAsLocal($sms : sms, customer==$customer) not ChargeAsFree(sms==$sms) Modifier($modifier : modifier, sms==$sms) then BigDecimal price = $modifier * 1.5; log.info(“Charge {} as {}”, $sms, price); insertLogical( new SmsBillingRecord($customer, price, $sms) ); end
![Page 34: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/34.jpg)
ВЫ ЧТО, ВСЕ ЕЩЕ КОДИТЕ БИЗНЕС -ПРАВИЛА?
Domain Specific Language
![Page 35: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/35.jpg)
Drools: Тариф «Хитрый» стр. 4+
rule “Billing: charge local in –Smart-” when $customer : Customer(tariff==Tariff.SMART) ChargeAsLocal($sms : sms, customer==$customer) not ChargeAsFree(customer==$customer, sms==$sms) Modifier($modifier : modifier, sms==$sms) then BigDecimal price = $modifier * 1.5; log.info(“Charge {} as {}”, $sms, price); insertLogical( new SmsBillingRecord($customer, price, $sms) ); end
![Page 36: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/36.jpg)
DSL: Тариф «Хитрый» стр. 4+
rule “Billing: charge local in –Smart-” when Find a customer - with Tariff.SMART Find customer’s local SMS Proceed only if it is not free Find an SMS modifier then Create SMS billing record with base price: 1.5 end
![Page 37: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/37.jpg)
DSL Словарь
[when] Find a customer = $customer : Customer() [when] - with {tariff} = tariff=={tariff} [when] Find customer’s local SMS = ChargeAsLocal($sms : sms, customer==$customer)
...
...
...
...
... [then] Create SMS billing record with base price: {base} = BigDecimal price = $modifier * {base}; log.info(“Charge {} as {}”, $sms, price); insertLogical(new SmsBillingRecord($customer, price, $sms));
![Page 38: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/38.jpg)
ЛЕКАРСТВО ОТ РАБСТВА
Тестирование
![Page 39: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/39.jpg)
Подсказки
Работаем с production knowledge base
Готовим крошечные тестовые данные
Выбираем дружелюбные критерии прохождения
Тестируем business case, а не Drools
Performance тесты тоже важны
![Page 40: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/40.jpg)
Тестируем Drools:
private final Customer callee = new Customer(“007”, Tariff.SIMPLE); private final Interval billingPeriod = new Interval( new DateTime(2013, 9, 1, 0, 0, 0, 0), new DateTime(2013, 10, 1, 0, 0, 0, 0) ); @Test public void testSimple() { DateTime instant = new DateTime(2013, 9, 20, 4, 40, 11); BigDecimal expectedResult = new BigDecimal(“2.0”); BigDecimal actualResult = executeGetAmount(callee, generateSMS(“007”, “any”, instant, 0, 1), billingPeriod, callee ); assertEquals(expectedResult, actualResult); }
![Page 41: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/41.jpg)
ЕЩЕ ЧУТЬ-ЧУТЬ И ПЕРЕРЫВ
Итоги
![Page 42: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/42.jpg)
Достоинства
Отделение логики от «бизнес-логики»
Независимые правила
Менять правила может даже аналитик
Тесты свободные от Mock-ов
«Теплый, ламповый» Java код
Приемлемая производительность
... и другая куча «плюшек»
![Page 43: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/43.jpg)
Смотри Также
JBoss Drools Guvnor
JBoss Drools Fusion
OptaPlanner (JBoss Drools Planner)
jBPM
http://www.jboss.org/drools/
http://www.jcp.org/en/jsr/detail?id=94
https://github.com/victor-cr/drools-joker-mobile
![Page 44: JBoss Drools Expert - 2013.jokerconf.com2013.jokerconf.com/presentations/...viktor_jboss_drools_expert_ru.pdf · 3+ лет программирования на Drools](https://reader035.vdocuments.mx/reader035/viewer/2022081503/5aae98c37f8b9adb688c8fde/html5/thumbnails/44.jpg)
ЗА ВНИМАНИЕ
Спасибо