بخش های اصلی

آموزش Drools

نمونه ای از برنامه ی Drools

در این بخش، یک پروژه ی Drools، برای مسئله ی زیر ایجاد می کنیم:

بسته به شهر و نوع محصول (ترکیبِ شهر و محصول)، مالیات محلیِ مربوط به آن شهر را پیدا کنین.

دو فایل DRL برای پروژه ی Droolsمان داریم. این دو فایل حاکی از دو شهری که درنظر گرفته ایم (Pune و Nagpur) و چهار نوع محصول (groceries, medicines, watches, and luxury goods)، هستن .

  • مالیاتِ medicines در هر دو شهر، صفر در نظر گرفته شده.
  • برای groceries، در شهر Pune، 2 روپیه و در شهر Nagpur، 1 روپیه مالیات درنظر گرفته ایم.

از قیمت فروشی یکسان برای نشان دادن تفاوت خروجی های نشان داده شده، استفاده کرده ایم. به یاد داشته باشین که همه ی ruleها در نرم افزار اجرا میشن.

در ادامه مدلی برای نگه داشتنِ itemType (نوع آیتم ها)، می بینین:

package com.sample;

import java.math.BigDecimal;

public class ItemCity {
   public enum City {
      PUNE, NAGPUR
   }
   
   public enum Type {
      GROCERIES, MEDICINES, WATCHES, LUXURYGOODS
   }
   
   private City purchaseCity;
   private BigDecimal sellPrice;
   private Type typeofItem;
   private BigDecimal localTax;
   
   public City getPurchaseCity() {
      return purchaseCity;
   }
   
   public void setPurchaseCity(City purchaseCity) {
      this.purchaseCity = purchaseCity;
   }
   
   public BigDecimal getSellPrice() {
      return sellPrice;
   }
   
   public void setSellPrice(BigDecimal sellPrice) {
      this.sellPrice = sellPrice;
   }
   
   public Type getTypeofItem() {
      return typeofItem;
   }
   
   public void setTypeofItem(Type typeofItem) {
      this.typeofItem = typeofItem;
   }
   
   public BigDecimal getLocalTax() {
      return localTax;
   }
   
   public void setLocalTax(BigDecimal localTax) {
      this.localTax = localTax;
   }
}

فایل های DRL

همانطور پیش تر نیز اشاره کردیم، در این جا از دو فایلِ DRL استفاده کرده ایم: Pune.drl و Nagpur.drl.

Pune.drl

فایلِ DRLای است که ruleهای شهر Pune را اجرا می کنه.

// created on: Dec 24, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

// declare any global variables here
dialect "java"
rule "Pune Medicine Item"
   
   when
      item : ItemCity (purchaseCity == ItemCity.City.PUNE,
                       typeofItem == ItemCity.Type.MEDICINES)
   
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Pune Groceries Item"
   
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE,
                      typeofItem == ItemCity.Type.GROCERIES)
   
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

Nagpur.drl

فایلِ DRLایِه که ruleهای شهر Nagpur.drl را اجرا می کنه.

// created on: Dec 26, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

// declare any global variables here
dialect "java"
rule "Nagpur Medicine Item"
   
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
                      typeofItem == ItemCity.Type.MEDICINES)

   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Nagpur Groceries Item"
   
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
                      typeofItem == ItemCity.Type.GROCERIES)

   then
      BigDecimal tax = new BigDecimal(1.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

فایل های DRLرا مبتنی بر شهر نوشتیم از آن جایی که در آینده قابلیت اضافه کردن ِهر تعداد فایل rule را در صورت اضافه شدن شهرهای جدید میده.

برای این که نشان بدیم همه ی ruleهای فایل های ruleمان اجرا میشن، از دو نوع آیتم استفاده کردیم (medicines and groceries)؛ برای هر شهر، medicine بدون مالیتِه و groceries مالیات داره.

کلاس test، فایل های rule را بارگزاری می کنه، factها را در session قرار میده و خروجی را تولید می کنه.

Droolstest.java

package com.sample;

import java.math.BigDecimal;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;

import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;

import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

import com.sample.ItemCity.City;
import com.sample.ItemCity.Type;

/* This is a sample class to launch a rule. */

public class DroolsTest {
   public static final void main(String[] args) {
      try {
      
         // load up the knowledge base
         KnowledgeBase kbase = readKnowledgeBase();
         StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
         
         ItemCity item1 = new ItemCity();
         item1.setPurchaseCity(City.PUNE);
         item1.setTypeofItem(Type.MEDICINES);
         item1.setSellPrice(new BigDecimal(10));
         ksession.insert(item1);
         
         ItemCity item2 = new ItemCity();
         item2.setPurchaseCity(City.PUNE);
         item2.setTypeofItem(Type.GROCERIES);
         item2.setSellPrice(new BigDecimal(10));
         ksession.insert(item2);
         
         ItemCity item3 = new ItemCity();
         item3.setPurchaseCity(City.NAGPUR);
         item3.setTypeofItem(Type.MEDICINES);
         item3.setSellPrice(new BigDecimal(10));
         ksession.insert(item3);
         
         ItemCity item4 = new ItemCity();
         item4.setPurchaseCity(City.NAGPUR);
         item4.setTypeofItem(Type.GROCERIES);
         item4.setSellPrice(new BigDecimal(10));         
         ksession.insert(item4);
         
         ksession.fireAllRules();
         
         System.out.println(item1.getPurchaseCity().toString() + " " 
            + item1.getLocalTax().intValue());
         
         System.out.println(item2.getPurchaseCity().toString() + " "
            + item2.getLocalTax().intValue());
         
         System.out.println(item3.getPurchaseCity().toString() + " "
            + item3.getLocalTax().intValue());
         
         System.out.println(item4.getPurchaseCity().toString() + " "
            + item4.getLocalTax().intValue());
                            
      } catch (Throwable t) {
         t.printStackTrace();
      }
   }
   
   private static KnowledgeBase readKnowledgeBase() throws Exception {
   
      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
      
      kbuilder.add(ResourceFactory.newClassPathResource("Pune.drl"), ResourceType.DRL);
      kbuilder.add(ResourceFactory.newClassPathResource("Nagpur.drl"), ResourceType.DRL);
      
      KnowledgeBuilderErrors errors = kbuilder.getErrors();
      
      if (errors.size() > 0) {
         for (KnowledgeBuilderError error: errors) {
            System.err.println(error);
         }
         throw new IllegalArgumentException("Could not parse knowledge.");
      }
      
      KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
      kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
      
      return kbase;
   }
}

اگه این برنامه را اجرا کنین، خروجی آن بصورت زیر خواهد بود:

PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

برای هر دو شهرِ Pune و Nagpur، زمانی که آیتم، medicine باشه، مقدار tax (مالیات) محلی، صفرِه؛ در حالیکه زمانی که آیتم، یک محصولِ grocery باشه، tax (مالیات) بازای هر شهر وجود داره. می توان برای محصولاتِ دیگه، ruleهای بیش تری به فایل های DRL اضافه کرد.

فراخوانیِ یک تابعِ خارجی در یک فایلِ DRL

در ادامه نحوه ی فراخوانیِ یک تابع static (ایستا) از یک فایل جاوا به داخل فایل DRLتان را ، به شما نشان میدیم.

اول از همه، کلاس HelloCity.java را در همان پکیج com.sample، ایجاد کنین.

package com.sample;

public class HelloCity {
   public static void writeHello(String name) {
      System.out.println("HELLO " + name + "!!!!!!");
   }
}

سپس، عبارت import را جهت فراخوانیِ متدِ writeHello از فایل DRL، در فایلِ DRL اضافه کنین. در قطعه کد زیر، تغییراتِ فایلِ DRL، Pune.drl، وجود دارند.

// created on: Dec 24, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;
 
import com.sample.HelloCity;

//declare any global variables here
dialect "java"

rule "Pune Medicine Item"

   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, typeofItem == ItemCity.Type.MEDICINES)

   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
      HelloCity.writeHello(item.getPurchaseCity().toString());
end

rule "Pune Groceries Item"

   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, typeofItem == ItemCity.Type.GROCERIES)
   
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

دوباره برنامه را اجرا کنین، خروجی آن بصورت زیر خواهد بود:

HELLO PUNE!!!!!!
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

تفاوت این خروجی با خروجی ِ قبلی، با رنگ زرد مشخص شده و بخروجیِ یک متدِ static (ایستا) در کلاس جاوا را به شما نشان میده.

مزیت فراخوانیِ متد جاوا اینه که می توانیم هر تابع utility/helperای (کمک کننده/ابزار) را در جاوا بنویسیم و همان را در فایل DRL فراخوانی کنیم.

در صورتی که سوال و یا نظری دارید، از بخش نظرات با ما در میان بگذارید.

خبـرنــامه

Newsletters

در خبــرنـامه سافت اسکیل عضو شویــد تا جدیدترین هـای سایت را بلافاصله در ایمیل خـود دریافت کنیـد

شما چه نظر و یا سوالی درباره این نوشته دارید؟

مبحث آموزشی

آموزش Drools

Learn Drools

پرســیدن سؤال جدید

سؤال های تخصصی خود را از ما بپرسید

دنبال کردن تلگرام کانال سافت اسکیل

https://telegram.me/softskill_ir

عملیات کاربران

خبـرنــامه

Newsletters

در خبــرنـامه سافت اسکیل عضو شویــد تا جدیدترین هـای سایت را بلافاصله در ایمیل خـود دریافت کنیـد