DroolsJAVA規(guī)則引擎(非常好的一篇教程)_第1頁
DroolsJAVA規(guī)則引擎(非常好的一篇教程)_第2頁
DroolsJAVA規(guī)則引擎(非常好的一篇教程)_第3頁
DroolsJAVA規(guī)則引擎(非常好的一篇教程)_第4頁
DroolsJAVA規(guī)則引擎(非常好的一篇教程)_第5頁
已閱讀5頁,還剩23頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、DroolsJA VA 規(guī)則引擎(非常好的一篇教程)Drools 是一個(gè)基于java 的規(guī)則引擎,開源的,可以將復(fù)雜多變的規(guī)則從硬編碼中解放出來,以規(guī)則腳本的形式存放在文件中,使得規(guī)則的變更不需要修正代碼重啟機(jī)器就可以立即在線上環(huán)境生效。本文所使用的demo 已上傳 HYPERLINK /source/3002213 /source/3002213Drools 語法開始語法之前首先要了解一下drools 的基本工作過程,通常而言我們使用一個(gè)接口來做事情,首先要穿進(jìn)去參數(shù),其次要獲取到接口的實(shí)現(xiàn)執(zhí)行完畢后的結(jié)果,而drools 也是一樣的,我們需要傳遞進(jìn)去數(shù)據(jù),用于規(guī)則的檢查,調(diào)用外部接口,同時(shí)

2、還可能需要獲取到規(guī)則執(zhí)行完畢后得到的結(jié)果。在drools 中, 這個(gè)傳遞數(shù)據(jù)進(jìn)去的對(duì)象,術(shù)語叫 Fact對(duì)象。 Fact對(duì)象是一個(gè)普通的java bean,規(guī)則中可以對(duì)當(dāng)前的對(duì)象進(jìn)行任何的讀寫操作,調(diào)用該對(duì)象提供的方法,當(dāng)一個(gè)java bean插入到 workingMemory 中,規(guī)則使用的是原有對(duì)象的引用,規(guī)則通過對(duì)fact 對(duì)象的讀寫,實(shí)現(xiàn)對(duì)應(yīng)用數(shù)據(jù)的讀寫,對(duì)于其中的屬性,需要提供getter setter 訪問器,規(guī)則中,可以動(dòng)態(tài)的往當(dāng)前workingMemory 中插入刪除新的fact 對(duì)象。規(guī)則文件可以使用.drl 文件,也可以是xml 文件,這里我們使用 drl 文件。規(guī)則語法:

3、package:對(duì)一個(gè)規(guī)則文件而言,package是必須定義的,必須放在規(guī)則文件第一行。特別的是,package的名字是隨意的, 不必必須對(duì)應(yīng)物理路徑,跟 java 的package的概念不同,這里只是邏輯上的一種區(qū)分。同樣的package下定義的function 和 query等可以直接使用。比如: package com.drools.demo.pointimport:導(dǎo)入規(guī)則文件需要使用到的外部變量,這里的使用方法跟 java 相同,但是不同于java 的是,這里的import 導(dǎo)入的不僅僅可以是一個(gè)類,也可以是這個(gè)類中的某一個(gè)可訪問的靜態(tài)方法。比如:import com.drools.

4、demo.point.PointDomain;import com.drools.demo.point.PointDomain.getById;rule:定義一個(gè)規(guī)則。rule ruleName 。一個(gè)規(guī)則可以包含三個(gè)部分:屬性部分:定義當(dāng)前規(guī)則執(zhí)行的一些屬性等,比如是否可被重復(fù)執(zhí)行、過期時(shí)間、生效時(shí)間等。條件部分,即LHS,定義當(dāng)前規(guī)則的條件,如whenMessage(); 判斷當(dāng)前workingMemory 中是否存在Message對(duì)象。結(jié)果部分,即RHS, 這里可以寫普通java 代碼, 即當(dāng)前規(guī)則條件滿足后執(zhí)行的操作,可以直接調(diào)用Fact對(duì)象的方法來操作應(yīng)用。規(guī)則事例:rule nam

5、eno-loop truewhen$message:Message(status = 0)thenSystem.out.println(fit);$message.setStatus(1);update($message);end上述的屬性中:no-loop : 定義當(dāng)前的規(guī)則是否不允許多次循環(huán)執(zhí)行,默認(rèn)是false,也就是當(dāng)前的規(guī)則只要滿足條件,可以無限次執(zhí)行。什么情況下會(huì)出現(xiàn)一條規(guī)則執(zhí)行過一次又被多次重復(fù)執(zhí)行呢? drools 提供了一些api, 可以對(duì)當(dāng)前傳入workingMemory中的 Fact 對(duì)象進(jìn)行修改或者個(gè)數(shù)的增減,比如上述的update方法,就是將當(dāng)前的workingMem

6、ory 中的 Message類型的Fact對(duì)象進(jìn)行屬性更新,這種操作會(huì)觸發(fā)規(guī)則的重新匹配執(zhí)行, 可以理解為Fact 對(duì)象更新了,所以規(guī)則需要重新匹配一遍, 那么疑問是之前規(guī)則執(zhí)行過并且修改過的那些Fact對(duì)象的屬性的數(shù)據(jù)會(huì)不會(huì)被重置?結(jié)果是不會(huì),已經(jīng)修改過了就不會(huì)被重置,update之后, 之前的修改都會(huì)生效。當(dāng)然對(duì) Fact對(duì)象數(shù)據(jù)的修改并不是一定需要調(diào)用update才可以生效,簡(jiǎn)單的使用set方法設(shè)置就可以完成,這里類似于java 的引用調(diào)用,所以何時(shí)使用update是一個(gè)需要仔細(xì)考慮的問題,一旦不慎, 極有可能會(huì)造成規(guī)則的死循環(huán)。上述的 no-loop true,即設(shè)置當(dāng)前的規(guī)則,只執(zhí)行

7、一次,如果本身的RHS 部分有update等觸發(fā)規(guī)則重新執(zhí)行的操作,也不要再次執(zhí)行當(dāng)前規(guī)則。但是其他的規(guī)則會(huì)被重新執(zhí)行,豈不是也會(huì)有可能造成多次重復(fù)執(zhí)行,數(shù)據(jù)紊亂甚至死循環(huán)?答案是使用其他的標(biāo)簽限制,也是可以控制的:lock-on-active truelock-on-active true :通過這個(gè)標(biāo)簽,可以控制當(dāng)前的規(guī)則只會(huì)被執(zhí)行一次,因?yàn)橐粋€(gè)規(guī)則的重復(fù)執(zhí)行不一定是本身觸發(fā)的,也可能是其他規(guī)則觸發(fā)的,所以這個(gè)是no-loop 的加強(qiáng)版。當(dāng)然該標(biāo)簽正規(guī)的用法會(huì)有其他的標(biāo)簽的配合,后續(xù)提及。date-expires:設(shè)置規(guī)則的過期時(shí)間,默認(rèn)的時(shí)間格式:“日 -月 -年” ,中英文格式相同,但

8、是寫法要用各自對(duì)應(yīng)的語言,比如中文:29-七月-2010,但是還是推薦使用更為精確和習(xí)慣的格式,這需要手動(dòng)在java 代碼中設(shè)置當(dāng)前系統(tǒng)的時(shí)間格式,后續(xù)提及。屬性用法舉例:date-expires 2011-01-3123:59:59 / 這里我們使用了更為習(xí)慣的時(shí)間格式date-effective:設(shè)置規(guī)則的生效時(shí)間,時(shí)間格式同上。duration:規(guī)則定時(shí),duration 30003 秒后執(zhí)行規(guī)則salience:優(yōu)先級(jí),數(shù)值越大越先執(zhí)行,這個(gè)可以控制規(guī)則的執(zhí)行順序。其他的屬性可以參照相關(guān)的api 文檔查看具體用法,此處略。規(guī)則的條件部分,即LHS 部分:when:規(guī)則條件開始。條件可以

9、單個(gè),也可以多個(gè),多個(gè)條件一次排列,比如wheneval(true)$customer:Customer()$message:Message(status=0)上述羅列了三個(gè)條件,當(dāng)前規(guī)則只有在這三個(gè)條件都匹配的時(shí)候才會(huì)執(zhí)行RHS 部分,三個(gè)條件中第一個(gè)eval(true):是一個(gè)默認(rèn)的api, true 無條件執(zhí)行,類似于while(true)$message:Message(status=0) 這句話標(biāo)示的:當(dāng)前的workingMemory 存在 Message類型并且status 屬性的值為0的 Fact 對(duì)象, 這個(gè)對(duì)象通常是通過外部java 代碼插入或者自己在前面已經(jīng)執(zhí)行的規(guī)則的RH

10、S 部分中 insert進(jìn)去的。前面的$message代表著當(dāng)前條件的引用變量,在后續(xù)的條件部分和 RHS 部分中, 可以使用當(dāng)前的變量去引用符合條件的FACT 對(duì)象,修改屬性或者調(diào)用方法等??蛇x,如果不需要使用,則可以不寫。條件可以有組合,比如:Message(status=0 | (status 1 & status=100)RHS中對(duì) Fact對(duì)象 private屬性的操作必須使用getter和 setter方法,而RHS 中則必須要直接用.的方法去使用,比如$order:Order(name=qu)$message:Message(status=0 & orders contains$

11、order & $=qu)特別的是,如果條件全部是& 關(guān)系, 可以使用 “ ,”來替代,但是兩者不能混用如果現(xiàn)在Fact對(duì)象中有一個(gè)List,需要判斷條件,如何判斷呢?看一個(gè)例子:Message int status;List names;$message:Message(status=0 & names contains 網(wǎng)易 & names.size = 1)上述的條件中,status必須是0, 并且names列表中含有“網(wǎng)易”并且列表長(zhǎng)度大于等于 1contains: 對(duì)比是否包含操作,操作的被包含目標(biāo)可以是一個(gè)復(fù)雜對(duì)象也可以是一個(gè)簡(jiǎn)單的值。Drools 提供了十二中類型比較操作符: =

12、 = != contains / not contains /memberOf / not memberOf /matches/ not matches not contains:與 contains 相反。memberOf:判斷某個(gè)Fact屬性值是否在某個(gè)集合中,與contains 不同的是他被比較的對(duì)象是一個(gè)集合,而contains被比較的對(duì)象是單個(gè)值或者對(duì)象。not memberOf:正好相反。matches:正則表達(dá)式匹配,與java 不同的是,不用考慮/的轉(zhuǎn)義問題not matches:正好相反。規(guī)則的結(jié)果部分當(dāng)規(guī)則條件滿足,則進(jìn)入規(guī)則結(jié)果部分執(zhí)行,結(jié)果部分可以是純 java 代碼,

13、比如:thenSystem.out.println(OK); / 會(huì)在控制臺(tái)打印出okend 當(dāng)然也可以調(diào)用Fact的方法, 比如$message.execute();操作數(shù)據(jù)庫等等一切操作。 結(jié)果部分也有drools 提供的方法:insert:往當(dāng)前workingMemory 中插入一個(gè)新的Fact對(duì)象,會(huì)觸發(fā)規(guī)則的再次執(zhí)行,除非使用no-loop 限定;update:更新 modify:修改,與update語法不同,結(jié)果都是更新操作retract:刪除 RHS 部分除了調(diào)用Drools 提供的 api 和 Fact對(duì)象的方法,也可以調(diào)用規(guī)則文件中定義的方法,方法的定義使用function關(guān)

14、鍵字 function void console System.out.println(); StringUtils.getId();/ 調(diào)用外部靜態(tài)方法,StringUtils 必須使用 import 導(dǎo)入, getId()必須是靜態(tài)方法Drools 還有一個(gè)可以定義類的關(guān)鍵字:declare 可以再規(guī)則文件中定義一個(gè)class,使用起來跟普通java對(duì)象相似,你可以在RHS部分中 new一個(gè)并且使用getter和 setter 方法去操作其屬性。declare Addressauthor(quzishen) / 元數(shù)據(jù),僅用于描述信息createTime(2011-1-24)city :

15、String maxLengh(100)postno : intend上述的 是什么呢?是元數(shù)據(jù)定義,用于描述數(shù)據(jù)的數(shù)據(jù),沒什么執(zhí)行含義你可以在RHS 部分中使用Address address = new Address()的方法來定義一個(gè)對(duì)象。更多的規(guī)則語法,可以參考其他互聯(lián)網(wǎng)資料,推薦: HYPERLINK /view/a6516373f242336c1eb95e7c.html /view/a6516373f242336c1eb95e7c.html(寫的很基礎(chǔ),但是部分語法寫的有些簡(jiǎn)單,含糊不好理解)Drools 應(yīng)用實(shí)例:現(xiàn)在我們模擬一個(gè)應(yīng)用場(chǎng)景:網(wǎng)站伴隨業(yè)務(wù)產(chǎn)生而進(jìn)行的積分發(fā)放操作。比

16、如支付寶信用卡還款獎(jiǎng)勵(lì)積分等。發(fā)放積分可能伴隨不同的運(yùn)營(yíng)策略和季節(jié)性調(diào)整,發(fā)放數(shù)目和規(guī)則完全不同,如果使用硬編碼的方式去伴隨業(yè)務(wù)調(diào)整而修改,代碼的修改、管理、優(yōu)化、測(cè)試、上線將是一件非常麻煩的事情,所以,將發(fā)放規(guī)則部分提取出來,交給Drools管理,可以極大程度的解決這個(gè)問題。(注意一點(diǎn)的是,并非所有的規(guī)則相關(guān)內(nèi)容都建議使用Drools,這其中要考慮系統(tǒng)會(huì)運(yùn)行多久,規(guī)則變更頻率等一系列條件,如果你的系統(tǒng)只會(huì)在線上運(yùn)行一周,那根本沒必要選擇 Drools 來加重你的開發(fā)成本,java 硬編碼的方式則將是首選)我們定義一下發(fā)放規(guī)則:積分的發(fā)放參考因素有:交易筆數(shù)、交易金額數(shù)目、信用卡還款次數(shù)、生日

17、特別優(yōu)惠等。定義規(guī)則:/ 過生日,則加10 分,并且將當(dāng)月交易比數(shù)翻倍后再計(jì)算積分 TOC o 1-5 h z / 2011-01-08 - 2011-08-08 每月信用卡還款3 次以上,每滿3筆贈(zèng)送 30 分/ 當(dāng)月購(gòu)物總金額100 以上,每100 元贈(zèng)送 10 分/ 當(dāng)月購(gòu)物次數(shù)5 次以上,每五次贈(zèng)送50 分/ 特別的,如果全部滿足了要求,則額外獎(jiǎng)勵(lì)100 分/ 發(fā)生退貨,扣減10 分/ 退貨金額大于100,扣減100 分在事先分析過程中,我們需要全面的考慮對(duì)于積分所需要的因素,以此整理抽象Fact 對(duì)象,通過上述的假設(shè)條件,我們假設(shè)積分計(jì)算對(duì)象如下:java view plaincop

18、y/* 積分計(jì)算對(duì)象* authorquzishen */ public class PointDomain / 用戶名private String userName; / 是否當(dāng)日生日privateboolean birthDay; / 增加積分?jǐn)?shù)目private longpoint; / 當(dāng)月購(gòu)物次數(shù)private int buyNums;/ 當(dāng)月退貨次數(shù)private int backNums; / 當(dāng)月購(gòu)物總金額private double buyMoney; / 當(dāng)月退貨總金額private double backMondy; / 當(dāng)月信用卡還款次數(shù)private int billT

19、hisMonth; TOC o 1-5 h z /* 記錄積分發(fā)送流水,防止重復(fù)發(fā)放*param userName 用戶名* param type 積分發(fā)放類型*/ public void recordPointLog(String userName,String type)System.out.println( 增加對(duì)+userName+ 的類型為+type+ 的積分操作記錄.);public String getUserName() returnuserName; / 其他 getter setter 方法省略定義積分規(guī)則接口java view plaincopy/* * 規(guī)則接口* au

20、thor quzishen*/ public interface PointRuleEngine /* 初始化規(guī)則引擎*/ public void initEngine();/* 刷新規(guī)則引擎中的規(guī)則*/ publicvoid refreshEnginRule();/* 執(zhí)行規(guī)則引擎* param pointDomain 積分 Fact */ public void executeRuleEngine(final PointDomain pointDomain); 規(guī)則接口實(shí)現(xiàn),Drools 的 API 很簡(jiǎn)單, 可以參考相關(guān)API 文檔查看具體用法:java view plaincopyim

21、port java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; import org.drools.RuleBase; import org.drools.StatefulSession; import piler.DroolsParserException; import piler.Pa

22、ckageBuilder; import org.drools.spi.Activation; /* 規(guī)則接口實(shí)現(xiàn)類*author quzishen */ public class PointRuleEngineImpl implements PointRuleEngine private RuleBase ruleBase;/* (non-Javadoc) * seecom.drools.demo.point.PointRuleEngine#initEngine() */ public void initEngine() / 設(shè)置時(shí)間格式System.setProperty(drools.d

23、ateformat, yyyy-MM-dd HH:mm:ss);ruleBase =RuleBaseFacatory.getRuleBase();tryPackageBuilder backageBuilder = getPackageBuilderFromDrlFile();ruleBase.addPackages(backageBuilder.getPackages(); catch (DroolsParserException e) catch catche.printStackTrace();(IOException e)e.printStackTrace();(Exception e

24、)e.printStackTrace();/* (non-Javadoc) * see com.drools.demo.point.PointRuleEngine#refreshEnginRule()*/ public void refreshEnginRule() ruleBase= RuleBaseFacatory.getRuleBase();org.drools.rule.Package packages = ruleBase.getPackages();for(org.drools.rule.Package pg : packages)ruleBase.removePackage(pg

25、.getName();initEngine(); /* (non-Javadoc) * see com.drools.demo.point.PointRuleEngine#executeRuleEngine(co m.drools.demo.point.PointDomain) */ public void executeRuleEngine(final PointDomain pointDomain)if(null = ruleBase.getPackages() | 0 =ruleBase.getPackages().length)return;StatefulSession statef

26、ulSession = ruleBase.newStatefulSession(); statefulSession.insert(pointDomain);/firestatefulSession.fireAllRules(neworg.drools.spi.AgendaFilter() public booleanaccept(Activation activation) return !activation.getRule().getName().contains(_test););statefulSession.dispose(); /* 從 Drl規(guī)則文件中讀取規(guī)則* return

27、* throwsException */ private PackageBuilder getPackageBuilderFromDrlFile() throws Exception / 獲取測(cè)試腳本文件List drlFilePath = getTestDrlFile();/裝載測(cè)試腳本文件List readers =readRuleFromDrlFile(drlFilePath); PackageBuilder backageBuilder = new PackageBuilder(); for (Reader r : readers) backageBuilder.addPackageF

28、romDrl(r);/ 檢查腳本是否有問題if(backageBuilder.hasErrors() throw newException(backageBuilder.getErrors().toString();return backageBuilder; /* paramdrlFilePath 腳本文件路徑* return * throwsFileNotFoundException */ privateList readRuleFromDrlFile(ListdrlFilePath) throws FileNotFoundException if (null = drlFilePath

29、| 0 = drlFilePath.size()return null;List readers = new ArrayList();for (String ruleFilePath : drlFilePath)readers.add(new FileReader(newFile(ruleFilePath);readers; * returngetTestDrlFile() return/* 獲取測(cè)試規(guī)則文件*/private ListList drlFilePath =new ArrayList();drlFilePath.add(D:/workspace2/DroolsDemo/src/c

30、om/drools/demo/point/addpoint.drl);drlFilePath.add(D:/workspace2/DroolsDemo/src/com/drools/demo/point/subpoint.drl);return drlFilePath; 為了獲取單實(shí)例的RuleBase,我們定義一個(gè)工廠類 java view plaincopyimport org.drools.RuleBase; importorg.drools.RuleBaseFactory; /* RuleBaseFacatory 單實(shí)例 RuleBase 生成工具* author quzishen *

31、/ publicclass RuleBaseFacatory private static RuleBase ruleBase;public static RuleBasegetRuleBase()return null != ruleBase ? ruleBase :RuleBaseFactory.newRuleBase(); 剩下的就是定義兩個(gè)規(guī)則文件,分別用于積分發(fā)放和積分扣 減 addpoint.drljava view plaincopypackage com.drools.demo.point import com.drools.demo.point.PointDomain; ru

32、le birthdayPoint / 過生日,則加10 分,并且將當(dāng)月交易比數(shù)翻倍后再計(jì)算積分salience 100lock-on-active true when$pointDomain :PointDomain(birthDay = true) then $pointDomain.setPoint($pointDomain.getPoint()+10);$pointDomain.setBuyNums($pointDomain.getBuyNums()*2); $pointDomain.setBuyMoney($pointDomain.getBuyMoney()*2); $pointDom

33、ain.setBillThisMonth($pointDomain.getBillThisMon th()*2);$pointDomain.recordPointLog($pointDomain.getUserName(), birthdayPoint); end rule billThisMonthPoint / 2011-01-08 - 2011-08-08 每月信用卡還款3 次以上,每滿3筆贈(zèng)送 30 分salience 99lock-on-active truedate-effective 2011-01-08 23:59:592011-08-08 23:59:59 whendate-

34、expires$pointDomain : thenPointDomain(billThisMonth = 3) $pointDomain.setPoint($pointDomain.getPoint()+$pointDomain .getBillThisMonth()/3*30);$pointDomain.recordPointLog($pointDomain.getUserName(), billThisMonthPoint); end rule buyMoneyPoint / 當(dāng)月購(gòu)物總金額100 以上, 每 100 元贈(zèng)送 10 分salience 98 lock-on-active

35、true when $pointDomain : PointDomain(buyMoney = 100) then$pointDomain.setPoint($pointDomain.getPoint()+ (int)$pointDomain.getBuyMoney()/100 * 10);$pointDomain.recordPointLog($pointDomain.getUserName(), buyMoneyPoint); end rule buyNumsPoint / 當(dāng)月 購(gòu)物次數(shù)5 次以上,每五次贈(zèng)送50 分salience 97lock-on-active true when$

36、pointDomain :PointDomain(buyNums = 5) then $pointDomain.setPoint($pointDomain.getPoint()+$pointDomain .getBuyNums()/5 * 50);$pointDomain.recordPointLog($pointDomain.getUserName(),buyNumsPoint); end rule allFitPoint / 特別的, 如果全部滿足了要求,則額外獎(jiǎng)勵(lì)100 分salience 96lock-on-active true when$pointDomain:PointDomai

37、n(buyNums = 5 & billThisMonth = 3 & buyMoney = 100) then$pointDomain.setPoint($pointDomain.getPoint()+ 100);$pointDomain.recordPointLog($pointDomain.getUserName(),a llFitPoint); endsubpoint.drljava view plaincopypackage com.drools.demo.pointimport com.drools.demo.point.PointDomain; rule subBackNumsP

38、oint / 發(fā)生退貨,扣減10 分salience 10 lock-on-active true when$pointDomain : PointDomain(backNums = 1)then$pointDomain.setPoint($pointDomain.getPoint()-10);$pointDomain.recordPointLog($pointDomain.getUserName(),s ubBackNumsPoint); end rule subBackMondyPoint / 退貨金額大于100,扣減100 分salience 9lock-on-active true w

39、hen$pointDomain :PointDomain(backMondy = 100)then$pointDomain.setPoint($pointDomain.getPoint()-10);$pointDomain.recordPointLog($pointDomain.getUserName(),s ubBackMondyPoint); end測(cè)試方法:java view plaincopypublic static void main(String args) throws IOException PointRuleEnginepointRuleEngine = new PointRuleEngineImpl();while(true)InputStream is = System.in;BufferedReader br = new B

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論