Drools - Hướng dẫn Nhanh

Bất kỳ ứng dụng Java cấp doanh nghiệp nào cũng có thể được chia thành ba phần:

  • UI - Giao diện người dùng (Giao diện người dùng)
  • Lớp dịch vụ lần lượt được kết nối với cơ sở dữ liệu
  • Lớp kinh doanh

Chúng tôi có một số khung công tác xử lý giao diện người dùng và lớp dịch vụ cùng nhau, ví dụ: Spring và Struts. Tuy nhiên, chúng tôi không có một cách tiêu chuẩn để xử lý logic nghiệp vụ cho đến khi Drools ra đời.

Drools là gì?

Drools là một Business Logic integration Platform (BLiP). Nó được viết bằng Java. Đây là một dự án mã nguồn mở được hỗ trợ bởi JBoss và Red Hat, Inc. Nó mở rộng và triển khai thuật toán so khớp Rete Pattern.

Theo thuật ngữ của giáo dân, Drools là một tập hợp các công cụ cho phép chúng ta phân tách và lập luận dựa trên logic và dữ liệu được tìm thấy trong các quy trình kinh doanh. Hai từ khóa quan trọng chúng ta cần lưu ý làLogicData.

Drools được chia thành hai phần chính: AuthoringRuntime.

  • Authoring - Quá trình cấp quyền liên quan đến việc tạo tệp Quy tắc (tệp .DRL).

  • Runtime - Nó liên quan đến việc tạo ra bộ nhớ làm việc và xử lý việc kích hoạt.

Rule Engine là gì?

Drools là Công cụ quy tắc hoặc Hệ thống quy tắc sản xuất sử dụng phương pháp tiếp cận dựa trên quy tắc để triển khai và Hệ thống chuyên gia. Hệ chuyên gia là hệ thống dựa trên tri thức sử dụng biểu diễn tri thức để xử lý tri thức thu được thành cơ sở tri thức có thể được sử dụng để lập luận.

Hệ thống Quy tắc Sản xuất là Turing hoàn chỉnh với trọng tâm là biểu diễn tri thức để thể hiện mệnh đề và logic bậc nhất một cách ngắn gọn, không mơ hồ và mang tính khai báo.

Bộ não của Hệ thống Quy tắc Sản xuất là Inference Enginecó thể mở rộng đến một số lượng lớn các quy tắc và sự kiện. Công cụ suy luận khớp các dữ kiện và dữ liệu với Quy tắc sản xuất - còn được gọi làProductions hoặc chỉ Rules - để suy ra kết luận dẫn đến hành động.

Quy tắc sản xuất là một cấu trúc gồm hai phần sử dụng logic bậc nhất để lập luận về biểu diễn tri thức. Công cụ quy tắc kinh doanh là một hệ thống phần mềm thực thi một hoặc nhiều quy tắc kinh doanh trong môi trường sản xuất thời gian chạy.

Công cụ quy tắc cho phép bạn xác định “What to Do" và không "How to do it. ”

Quy tắc là gì?

Các quy tắc là những phần kiến ​​thức thường được thể hiện dưới dạng, " Khi một số điều kiện xảy ra, sau đó thực hiện một số nhiệm vụ."

When
   <Condition is true>
Then
   <Take desired Action>

Phần quan trọng nhất của Quy tắc là whenphần. Nếuwhen một phần hài lòng, then một phần được kích hoạt.

rule  <rule_name>
   <attribute> <value>
      
   when
      <conditions>
      
   then
      <actions>
end

Khớp mẫu

Quá trình đối sánh các dữ kiện mới hoặc hiện có với các Quy tắc sản xuất được gọi là Khớp mẫu, được thực hiện bởi Công cụ suy luận. Có một số thuật toán được sử dụng để Đối sánh Mẫu bao gồm:

  • Linear
  • Rete
  • Treat
  • Leaps

Drools Triển khai và mở rộng Thuật toán Rete. Việc triển khai Drools Rete được gọi là ReteOO, biểu thị rằng Drools đã triển khai nâng cao và tối ưu hóa thuật toán Rete cho các hệ thống hướng đối tượng.

Ưu điểm của Rule Engine

Lập trình khai báo

Các quy tắc giúp bạn dễ dàng trình bày các giải pháp cho các vấn đề khó khăn và cũng xác minh các giải pháp. Không giống như mã, Quy tắc được viết bằng ngôn ngữ ít phức tạp hơn; Các nhà phân tích kinh doanh có thể dễ dàng đọc và xác minh một bộ quy tắc.

Phân tách logic và dữ liệu

Dữ liệu nằm trong Đối tượng miền và logic nghiệp vụ nằm trong Quy tắc. Tùy thuộc vào loại dự án, loại tách biệt này có thể rất thuận lợi.

Tốc độ và khả năng mở rộng

Thuật toán Rete OO mà Drools được viết đã là một thuật toán đã được chứng minh. Với sự trợ giúp của Drools, ứng dụng của bạn trở nên rất dễ mở rộng. Nếu có yêu cầu thay đổi thường xuyên, người ta có thể thêm các quy tắc mới mà không cần phải sửa đổi các quy tắc hiện có.

Tập trung hóa kiến ​​thức

Bằng cách sử dụng Quy tắc, bạn tạo ra một kho kiến ​​thức (cơ sở kiến ​​thức) có thể thực thi được. Đó là một điểm trung thực cho chính sách kinh doanh. Lý tưởng nhất là các Quy tắc dễ đọc đến mức chúng cũng có thể dùng làm tài liệu.

Tích hợp công cụ

Các công cụ như Eclipse cung cấp các cách để chỉnh sửa và quản lý các quy tắc cũng như nhận được phản hồi, xác nhận và hỗ trợ nội dung ngay lập tức. Các công cụ kiểm tra và gỡ lỗi cũng có sẵn.

Đây là các điều kiện tiên quyết để cài đặt Plugin Drools -

  • Java 1.5 (hoặc cao hơn) SE JDK
  • Eclipse 4.2 (hoặc bất kỳ phiên bản nào) và plugin Drools

Vì Drools là một BRMS (Hệ thống quản lý quy tắc kinh doanh) được viết bằng Java, chúng tôi sẽ trình bày cách thêm các plugin mong muốn trong phần này. Xem xét người dùng Java tối đa sử dụng Eclipse, hãy xem cách thêm plugin Drools 5.x.0 vào Eclipse.

Bước 1: Tải xuống Binaries

Tải xuống các tệp nhị phân từ liên kết sau -

https://download.jboss.org/drools/release/5.3.0.Final/

Sau khi tải xuống hoàn tất, hãy giải nén các tệp vào đĩa cứng của bạn.

Bước 2: Cài đặt phần mềm

Khởi chạy Eclipse và chuyển đến phần trợ giúp → cài đặt phần mềm mới. Nhấp vào Thêm như được hiển thị trong ảnh chụp màn hình sau.

Sau đó, nhấp vào Địa phương như được hiển thị ở đây và chọn "… / binaries / org.drools.updatesite".

Chọn Drools và jBPM và nhấp vào Tiếp theo.

Một lần nữa nhấp vào Tiếp theo. Sau đó, chấp nhận các điều khoản và thỏa thuận cấp phép và nhấp vào Hoàn tất.

Khi nhấp vào Kết thúc, quá trình cài đặt phần mềm bắt đầu -

Đăng cài đặt thành công, bạn sẽ nhận được hộp thoại sau:

Bấm vào có. Sau khi Eclipse khởi động lại, hãy chuyển đến Windows → Preferences

Bạn có thể xem Drools theo sở thích của mình. Cài đặt plugin Drools của bạn đã hoàn tất bây giờ.

Drools Runtime được yêu cầu để hướng dẫn người chỉnh sửa chạy chương trình với phiên bản cụ thể của Drools jar. Bạn có thể chạy chương trình / ứng dụng của mình với các Drools Runtime khác nhau.

Nhấp vào Windows → Preference → Drools → Thời gian chạy các Drools đã cài đặt. Sau đó nhấp vào Thêm như hiển thị trong ảnh chụp màn hình sau.

Sau đó, nhấp vào Create a new Drools Runtime như được hiển thị ở đây.

Nhập đường dẫn đến thư mục nhị phân nơi bạn đã tải xuống droolsjbpm-tools-distribution-5.3.0.Final.zip

Nhấp vào OK và đặt tên cho Drools Runtime. Thời gian chạy Drools hiện đã được tạo.

Để tạo một chương trình Drools cơ bản, hãy mở Eclipse. Đi tới Fileb → New → Project.

Chọn Dự án Drools. Đặt tên phù hợp cho dự án. Ví dụ, DroolsTest.

Màn hình tiếp theo sẽ nhắc bạn chọn một số tệp mà bạn muốn trong dự án Drools đầu tiên của mình.

Chọn hai tệp đầu tiên. Tệp đầu tiên là tệp .drl (Tệp Quy tắc Drools) và tệp thứ hai là một lớp Java để tải và thực thi quy tắc HelloWorld.

Nhấp vào Tiếp theo → Kết thúc.

Khi bạn nhấp vào Kết thúc, một dự án <DroolsTest> sẽ được tạo trong không gian làm việc của bạn. Mở lớp Java, sau đó nhấp chuột phải và chạy dưới dạng ứng dụng Java. Bạn sẽ thấy đầu ra như được hiển thị ở đây -

Tiếp theo, chúng ta sẽ thảo luận về các thuật ngữ thường được sử dụng trong Rule Engine.

Quy tắc

Trung tâm của Công cụ quy tắc nơi bạn chỉ định các điều kiện (nếu 'a' thì 'b').

Sự thật

Dữ kiện là dữ liệu mà các quy tắc sẽ thực hiện. Từ quan điểm Java, Facts là POJO (Đối tượng Java cũ thuần túy).

Phiên họp

Phiên kiến ​​thức trong Drools là thành phần cốt lõi để kích hoạt các quy tắc. Đây là phiên kiến ​​thức nắm giữ tất cả các quy tắc và các tài nguyên khác. Phiên kiến ​​thức được tạo từ Cơ sở kiến ​​thức.

Để công cụ quy tắc hoạt động, Dữ kiện được chèn vào phiên và khi một điều kiện được đáp ứng, quy tắc tiếp theo sẽ được kích hoạt. Phiên có hai loại -

  • Phiên kiến ​​thức không trạng thái
  • Phiên kiến ​​thức trạng thái

Chương trình nghị sự

Đó là một khái niệm hợp lý. Chương trình nghị sự là nơi hợp lý mà các kích hoạt đang chờ được kích hoạt.

Kích hoạt

Kích hoạt là thenmột phần của quy tắc. Kích hoạt được đặt trong chương trình nghị sự nơi quy tắc thích hợp được kích hoạt.

Nếu bạn thấy quy tắc mặc định được viết trong dự án Hello World (Sample.drl), có rất nhiều từ khóa được sử dụng mà chúng tôi sẽ giải thích ngay bây giờ.

Sample.drl

  • Package- Mọi Quy tắc bắt đầu bằng một tên gói. Gói hoạt động như một không gian tên cho các Quy tắc. Tên quy tắc trong một gói phải là duy nhất. Các gói trong Quy tắc tương tự như các gói trong Java.

  • Import statement- Bất kỳ sự kiện nào bạn muốn áp dụng quy tắc, những dữ kiện đó cần phải được nhập. Ví dụ: com.sample.DroolsTest.Message; trong ví dụ trên.

  • Rule Definition- Nó bao gồm Tên quy tắc, điều kiện và Hệ quả. Từ khóa Drools làrule, when, then,end. Trong ví dụ trên, tên quy tắc là “Hello World” và “GoodBye”. Cácwhen một phần là điều kiện trong cả quy tắc và thenmột phần là hệ quả. Trong thuật ngữ quy tắc,when một phần còn được gọi là LHS (bên tay trái) và then một phần như RHS (phía bên phải) của quy tắc.

Bây giờ chúng ta hãy xem qua các thuật ngữ được sử dụng trong tệp Java được sử dụng để tải Drools và thực thi các quy tắc.

Kiến thức cơ bản

Cơ sở tri thức là một giao diện quản lý tập hợp các quy tắc, quy trình và các kiểu nội bộ. Nó được chứa bên trong góiorg.drools.KnowledgeBase. Trong Drools, chúng thường được gọi làknowledge definitions hoặc là knowledge. Các định nghĩa kiến ​​thức được nhóm thànhknowledge packages. Định nghĩa kiến ​​thức có thể được thêm hoặc bớt. Mục đích chính của Cơ sở tri thức là lưu trữ và tái sử dụng chúng vì việc tạo ra chúng rất tốn kém. Cơ sở kiến ​​thức cung cấp các phương pháp để tạo phiên kiến ​​thức.

Phiên kiến ​​thức

Phiên kiến ​​thức được truy xuất từ ​​cơ sở kiến ​​thức. Đây là giao diện chính để tương tác với Drools Engine. Phiên kiến ​​thức có thể có hai loại -

  • Phiên kiến ​​thức không trạng thái

  • Phiên kiến ​​thức trạng thái

Phiên kiến ​​thức không trạng thái

Phiên kiến ​​thức không trạng thái là phiên không trạng thái tạo thành trường hợp sử dụng đơn giản nhất, không sử dụng suy luận. Một phiên không trạng thái có thể được gọi giống như một hàm, truyền cho nó một số dữ liệu và sau đó nhận lại một số kết quả. Các ví dụ phổ biến về phiên không trạng thái bao gồm:

  • Validation

    • Người này có đủ điều kiện để thế chấp không?

  • Calculation

    • Tính phí bảo hiểm thế chấp.

  • Routing and Filtering

    • Lọc các tin nhắn đến, chẳng hạn như email, vào các thư mục.

    • Gửi tin nhắn đến một điểm đến

Phiên kiến ​​thức trạng thái

Phiên trạng thái tồn tại lâu hơn và cho phép thay đổi lặp đi lặp lại theo thời gian. Một số trường hợp sử dụng phổ biến cho các phiên trạng thái bao gồm:

  • Monitoring

    • Giám sát và phân tích thị trường chứng khoán để mua bán tự động.

  • Diagnostics

    • Phát hiện lỗi, chẩn đoán y tế

  • Logistics

    • Theo dõi bưu kiện và cung cấp giao hàng

Người xây dựng kiến ​​thức

Giao diện KnoledgeBuilder chịu trách nhiệm xây dựng một Gói kiến ​​thức từ các định nghĩa kiến ​​thức (quy tắc, quy trình, kiểu). Nó được chứa bên trong góiorg.drools.builder.KnowledgeBuilder. Các định nghĩa kiến ​​thức có thể ở nhiều dạng khác nhau. Nếu có bất kỳ sự cố nào xảy ra với việc xây dựng, KnowledgeBuilder sẽ báo cáo lỗi thông qua hai phương pháp sau:hasErrorsgetError.

Sơ đồ sau giải thích quy trình

Trong ví dụ trên, vì chúng tôi đang lấy một ví dụ đơn giản về phiên kiến ​​thức không trạng thái, chúng tôi đã chèn dữ kiện vào phiên và sau đó phương thức fireAllRules () được gọi và bạn thấy đầu ra.

Trong trường hợp phiên kiến ​​thức trạng thái, khi các quy tắc được kích hoạt, đối tượng phiên kiến ​​thức trạng thái phải gọi phương thức dispose() để giải phóng phiên và tránh rò rỉ bộ nhớ.

Như bạn đã thấy .drl (tệp quy tắc) có cú pháp riêng của nó, hãy để chúng tôi trình bày một số phần của cú pháp Quy tắc trong chương này.

Điều kiện trong Quy tắc

Một quy tắc có thể chứa nhiều điều kiện và mẫu như:

  • Tài khoản (số dư == 200)
  • Khách hàng (tên == “Vivek”)

Các điều kiện trên kiểm tra xem Số dư tài khoản là 200 hay Tên khách hàng là “Vivek”.

Các biến trong quy tắc

Tên biến trong Drools bắt đầu bằng ký hiệu Dollar ($).

  • $ account - Tài khoản ()
  • $ account là biến cho lớp Account ()

Drools có thể hoạt động với tất cả các kiểu Java gốc và thậm chí cả Enum.

Nhận xét trong Quy tắc

Các ký tự đặc biệt, # hoặc //, có thể được sử dụng để đánh dấu các nhận xét một dòng.

Đối với nhận xét nhiều dòng, hãy sử dụng định dạng sau:

/*
   Another line
   .........
   .........
*/

Biến toàn cục

Biến toàn cục là các biến được gán cho một phiên. Chúng có thể được sử dụng vì nhiều lý do như sau:

  • Đối với các tham số đầu vào (ví dụ: các giá trị không đổi có thể được tùy chỉnh từ phiên này sang phiên khác).

  • Đối với các tham số đầu ra (ví dụ: báo cáo — một quy tắc có thể ghi một số thông báo vào một biến báo cáo chung).

  • Điểm truy cập cho các dịch vụ như ghi nhật ký, có thể được sử dụng trong các quy tắc.

Chức năng trong Quy tắc

Chức năng là một tính năng tiện lợi. Chúng có thể được sử dụng trong các điều kiện và hậu quả. Các hàm đại diện cho một sự thay thế cho các lớp tiện ích / trợ giúp. Ví dụ,

function double calculateSquare (double value) {
   return value * value;
}

Phương ngữ

Phương ngữ chỉ định cú pháp được sử dụng trong bất kỳ biểu thức mã nào nằm trong điều kiện hoặc hệ quả. Nó bao gồm các giá trị trả về, dấu hiệu, dấu hiệu nội dòng, vị từ, biểu thức phục hồi, hệ quả, v.v. Giá trị mặc định làJava. Drools hiện hỗ trợ thêm một phương ngữ gọi làMVEL. Phương ngữ mặc định có thể được chỉ định ở cấp độ gói như sau:

package org.mycompany.somePackage
dialect "mvel"

Phương ngữ MVEL

MVEL là một ngôn ngữ biểu thức cho các ứng dụng dựa trên Java. Nó hỗ trợ truy cập trường và phương thức / getter. Nó dựa trên cú pháp Java.

Salience

Khả năng phục hồi là một tính năng rất quan trọng của Cú pháp quy tắc. Khả năng phục hồi được sử dụng bởi chiến lược giải quyết xung đột để quyết định quy tắc nào sẽ kích hoạt trước. Theo mặc định, nó là tiêu chí chính.

Chúng ta có thể sử dụng khả năng phục hồi để xác định thứ tự của các quy tắc kích hoạt. Salience có một thuộc tính, nhận bất kỳ biểu thức nào trả về một số kiểu int (số dương cũng như số âm đều hợp lệ). Giá trị càng cao, thì chiến lược giải quyết xung đột càng có nhiều khả năng được chọn để kích hoạt.

salience ($account.balance * 5)

Giá trị đối tượng mặc định là 0. Chúng ta nên ghi nhớ điều này khi chỉ định giá trị đối tượng cho một số quy tắc.

Có rất nhiều tính năng / tham số khác trong Cú pháp quy tắc, nhưng chúng tôi chỉ đề cập đến những tính năng / thông số quan trọng ở đây.

Từ khóa kết quả quy tắc

Từ khoá Hệ quả của Quy tắc là những từ khoá được sử dụng trong “then”Một phần của quy tắc.

  • Modify - Các thuộc tính của dữ kiện có thể được sửa đổi trong then một phần của Quy tắc.

  • Insert - Dựa trên một số điều kiện, nếu đúng, người ta có thể chèn một dữ kiện mới vào phiên hiện tại của Rule Engine.

  • Retract - Nếu một điều kiện cụ thể là đúng trong một Quy tắc và bạn không muốn thực hiện bất kỳ điều gì khác với thực tế đó, bạn có thể rút lại thực tế cụ thể từ Công cụ quy tắc.

Note- Việc có một logic điều kiện (câu lệnh if) nằm trong một hệ quả quy tắc được coi là một thực hành rất xấu. Hầu hết các trường hợp, một quy tắc mới nên được tạo.

Trong chương này, chúng ta sẽ tạo một dự án Drools cho câu lệnh vấn đề sau:

Tùy thuộc vào thành phố và loại sản phẩm (Kết hợp giữa Thành phố và Sản phẩm), hãy tìm hiểu thuế địa phương liên quan đến thành phố đó.

Chúng tôi sẽ có hai tệp DRL cho dự án Drools của chúng tôi. Hai tệp DRL sẽ biểu thị hai thành phố được xem xét (Pune và Nagpur) và bốn loại sản phẩm (hàng tạp hóa, thuốc, đồng hồ và hàng xa xỉ).

  • Thuế thuốc ở cả hai thành phố được coi là bằng không.

  • Đối với hàng tạp hóa, chúng tôi đã giả định mức thuế là 2 Rs ở Pune và 1 Rs ở Nagpur.

Chúng tôi đã sử dụng cùng một mức giá bán để chứng minh các đầu ra khác nhau. Lưu ý rằng tất cả các quy tắc đang được kích hoạt trong ứng dụng.

Đây là mô hình để chứa từng 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;
   }
}

Tệp DRL

Như đã đề xuất trước đó, chúng tôi đã sử dụng hai tệp DRL ở đây: Pune.drl và Nagpur.drl.

Pune.drl

Đây là tệp DRL thực thi các quy tắc cho thành phố 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

Đây là tệp DRL thực thi các quy tắc cho thành phố Nagpur.

// 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

Chúng tôi đã viết các tệp DRL dựa trên thành phố, vì nó cung cấp cho chúng tôi khả năng mở rộng để thêm bất kỳ số lượng tệp quy tắc nào sau này nếu các thành phố mới đang được thêm vào.

Để chứng minh rằng tất cả các quy tắc đang được kích hoạt từ các tệp quy tắc của chúng tôi, chúng tôi đã sử dụng hai loại mặt hàng (thuốc và hàng tạp hóa); và thuốc được miễn thuế và hàng tạp hóa bị đánh thuế theo thành phố.

Lớp thử nghiệm của chúng tôi tải các tệp quy tắc, chèn dữ liệu vào phiên và tạo ra kết quả.

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;
   }
}

Nếu bạn chạy chương trình này, đầu ra của nó sẽ như sau:

PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

Đối với cả Pune và Nagpur, khi mặt hàng là thuốc, thuế địa phương bằng 0; trong khi khi mặt hàng là hàng tạp hóa, thuế sẽ tính theo thành phố. Các quy tắc khác có thể được thêm vào tệp DRL cho các sản phẩm khác. Đây chỉ là một chương trình mẫu.

Gọi một hàm bên ngoài biểu mẫu một tệp DRL

Ở đây chúng tôi sẽ trình bày cách gọi một hàm tĩnh từ tệp Java trong tệp DRL của bạn.

Trước hết, hãy tạo một lớp HelloCity.java trong cùng một gói com.sample.

package com.sample;

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

Sau đó, thêm câu lệnh nhập trong tệp DRL để gọi phương thức writeHello từ tệp DRL. Trong khối mã sau, các thay đổi trong tệp DRL Pune.drl được đánh dấu bằng màu vàng.

// 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

Chạy lại chương trình và kết quả của nó sẽ như sau:

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

Sự khác biệt bây giờ trong đầu ra được đánh dấu bằng màu vàng, hiển thị đầu ra của phương thức tĩnh trong lớp Java.

Ưu điểm khi gọi một phương thức Java là chúng ta có thể viết bất kỳ tiện ích / hàm trợ giúp nào trong Java và gọi phương thức tương tự từ tệp DRL.

Có nhiều cách khác nhau để gỡ lỗi dự án Drools. Ở đây, chúng tôi sẽ viết một lớp Tiện ích để cho bạn biết quy tắc nào đang được kích hoạt hoặc kích hoạt.

Với cách tiếp cận này, bạn có thể kiểm tra tất cả các quy tắc đang được kích hoạt trong dự án Drools của bạn. Đây là Lớp Tiện ích của chúng tôi

Utility.java

package com.sample;
import org.drools.spi.KnowledgeHelper;

public class Utility {
   public static void help(final KnowledgeHelper drools, final String message){
      System.out.println(message);
      System.out.println("\nrule triggered: " + drools.getRule().getName());
   }
   public static void helper(final KnowledgeHelper drools){
      System.out.println("\nrule triggered: " + drools.getRule().getName());
   }
}

Phương pháp đầu tiên help in quy tắc được kích hoạt cùng với một số thông tin bổ sung mà bạn có thể chuyển dưới dạng Chuỗi qua tệp DRL.

Quy tắc thứ hai helper in xem quy tắc cụ thể có được kích hoạt hay không.

Chúng tôi đã thêm một trong các phương thức Tiện ích trong mỗi tệp DRL. Chúng tôi cũng đã thêm chức năng nhập trong tệp DRL (Pune.drl). bên trongthenmột phần của quy tắc, chúng tôi đã thêm lệnh gọi hàm tiện ích. Pune.drl sửa đổi được đưa ra bên dưới. Các thay đổi được đánh dấu bằng màu xanh lam.

Pune.drl được sửa đổi

//created on: Dec 24, 2014
package droolsexample

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

// 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()); 
      helper(drools);
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())); 
      helper(drools);
end

Tương tự, chúng tôi đã thêm chức năng tiện ích khác trong tệp DRL thứ hai (Nagpur.drl). Đây là mã đã sửa đổi -

Nagpur.drl được sửa đổi

// created on: Dec 26, 2014
package droolsexample

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

//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())); 
      help(drools,"added info");
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())); 
      help(drools,"info");
end

Chạy lại chương trình và nó sẽ tạo ra kết quả sau:

info

rule triggered: Nagpur Groceries Item
added info

rule triggered: Nagpur Medicine Item

rule triggered: Pune Groceries Item
HELLO PUNE!!!!!!

rule triggered: Pune Medicine Item
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

Cả hai hàm tiện ích đều được gọi và nó cho biết quy tắc cụ thể có được gọi hay không. Trong ví dụ trên, tất cả các quy tắc đang được gọi, nhưng trong một ứng dụng doanh nghiệp, chức năng tiện ích này có thể thực sự hữu ích để gỡ lỗi và tìm hiểu xem một quy tắc cụ thể có bị kích hoạt hay không.

Sử dụng Phối cảnh gỡ lỗi trong Eclipse

Bạn có thể gỡ lỗi các quy tắc trong quá trình thực thi ứng dụng Drools của mình. Bạn có thể thêm các điểm ngắt vào hậu quả của các quy tắc của mình và bất cứ khi nào gặp phải điểm ngắt như vậy trong quá trình thực thi các quy tắc, việc thực thi sẽ tạm thời dừng lại. Sau đó, bạn có thể kiểm tra các biến đã biết tại thời điểm đó như khi bạn thực hiện trong Ứng dụng Java và sử dụng các tùy chọn gỡ lỗi thông thường có sẵn trong Eclipse.

Để tạo một điểm ngắt trong tệp DRL của bạn, chỉ cần bấm đúp vào dòng mà bạn muốn tạo điểm ngắt. Hãy nhớ rằng, bạn chỉ có thể tạo một điểm ngắt trongthenmột phần của quy tắc. Một điểm ngắt có thể được loại bỏ bằng cách nhấp đúp vào điểm ngắt trong trình chỉnh sửa DRL.

Sau khi áp dụng các điểm ngắt, bạn cần gỡ lỗi ứng dụng của mình dưới dạng ứng dụng Drools. Các điểm ngắt của Drools (các điểm ngắt trong tệp DRL) sẽ chỉ hoạt động nếu ứng dụng của bạn đang được gỡ lỗi dưới dạng ứng dụng Drools. Đây là cách bạn cần làm như vậy -

Khi bạn gỡ lỗi ứng dụng của mình dưới dạng ứng dụng Drools, bạn sẽ thấy điều khiển trên tệp DRL như được hiển thị trong ảnh chụp màn hình sau:

Bạn có thể thấy các biến và giá trị hiện tại của đối tượng tại điểm gỡ lỗi đó. Điều khiển tương tự của F6 để di chuyển đến dòng tiếp theo và F8 để nhảy đến điểm gỡ lỗi tiếp theo cũng được áp dụng ở đây. Bằng cách này, bạn có thể gỡ lỗi ứng dụng Drools của mình.

Note - Phối cảnh gỡ lỗi trong ứng dụng Drools chỉ hoạt động nếu phương ngữ là MVEL cho đến khi Drools 5.x.