日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java commons-chain_Apache commons chain 初探

發(fā)布時間:2025/3/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java commons-chain_Apache commons chain 初探 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Apache commons chain 是什么

Apache common chain 是對責(zé)任鏈設(shè)計(jì)模式的改造封裝,讓使用者更加方便的使用。

簡單回顧一下責(zé)任鏈設(shè)計(jì)模式

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述責(zé)任鏈(Chain of Responsibility)模式的:

責(zé)任鏈模式是一種對象的行為模式。在責(zé)任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發(fā)出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求,這使得系統(tǒng)可以在不影響客戶端的情況下動態(tài)地重新組織和分配責(zé)任

關(guān)鍵點(diǎn):

鏈?zhǔn)且幌盗泄?jié)點(diǎn)的集合

鏈的各個節(jié)點(diǎn)可隨意拆分和組裝

使多個對象都有機(jī)會處理請求,從而避免請求的發(fā)送者和接受者之間的耦合關(guān)系, 將這個對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理他為止。

責(zé)任鏈適用的場景

有多個的對象可以處理一個請求,哪個對象處理該請求運(yùn)行時刻自動確定。

你想在不明確指定接受者的情況下,想過個對象中的一個提交一個請求。

可處理一個請求的對象集合應(yīng)該被動態(tài)指定。

簡單例子

abstract class Handler {

private Handler nextHandler;

public Handler getNextHandler() {

return nextHandler;

}

public void setNextHandler(Handler nextHandler) {

this.nextHandler = nextHandler;

}

public abstract void doHandler();

}

class ConcreteHandler extends Handler {

@Override

public void doHandler() {

if (getNextHandler() != null) {

System.out.println("還有責(zé)任鏈");

getNextHandler().doHandler();

} else {

System.out.println("我自己處理" + toString());

}

}

}

設(shè)計(jì)模式主體架構(gòu):

角色:

抽象處理者角色(Handler):定義出一個處理請求的接口。如果需要,接口可以定義 出一個方法以設(shè)定和返回對下家的引用。這個角色通常由一個Java抽象類或者Java接口實(shí)現(xiàn)。 具體處理者角色(ConcreteHandler):具體處理者接到請求后,可以選擇將請求處理掉,或者將請求傳給下家。由于具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。 抽象處理者角色

public abstract class Handler {

/**

* 持有后繼的責(zé)任對象

*/

protected Handler successor;

/**

* 示意處理請求的方法,雖然這個示意方法是沒有傳入?yún)?shù)的

* 但實(shí)際是可以傳入?yún)?shù)的,根據(jù)具體需要來選擇是否傳遞參數(shù)

*/

public abstract void handleRequest();

/**

* 取值方法

*/

public Handler getSuccessor() {

return successor;

}

/**

* 賦值方法,設(shè)置后繼的責(zé)任對象

*/

public void setSuccessor(Handler successor) {

this.successor = successor;

}

}

具體處理者角色

public class ConcreteHandler extends Handler {

/**

* 處理方法,調(diào)用此方法處理請求

*/

@Override

public void handleRequest() {

/**

* 判斷是否有后繼的責(zé)任對象

* 如果有,就轉(zhuǎn)發(fā)請求給后繼的責(zé)任對象

* 如果沒有,則處理請求

*/

if(getSuccessor() != null)

{

System.out.println("放過請求");

getSuccessor().handleRequest();

}else

{

System.out.println("處理請求");

}

}

}

客戶端類:

public class Client {

public static void main(String[] args) {

//組裝責(zé)任鏈

Handler handler1 = new ConcreteHandler();

Handler handler2 = new ConcreteHandler();

handler1.setSuccessor(handler2);

//提交請求

handler1.handleRequest();

}

}

Apache CommonsChain

CommonsChain實(shí)現(xiàn)了Chain of Responsebility和Command模式,其中的Catalog + 配置文件的方式使得調(diào)用方和Command的實(shí)現(xiàn)方的耦合度大大的降低,提高了靈活性。

如何使用

簡單寫了一個實(shí)現(xiàn):

/**

*

Test implementation of Chain that exposes the

* getCommands() method publicy.

*/

public class TestChain extends ChainBase {

/**

* 獲取責(zé)任鏈中所有加入的命令

* @return 責(zé)任鏈中的命令

*/

public Command[] getCommands() {

return (commands);

}

public static void main(String[] args) throws Exception {

TestChain testChain=new TestChain();

Context context=new ContextBase();

/**

* 加入執(zhí)行命令1

*/

testChain.addCommand(new Command() {

public boolean execute(Context context) throws Exception {

System.out.println("執(zhí)行命令1");

return false;

}

});

/**

* 加入執(zhí)行命令2

* 注意:返回值為true 表示執(zhí)行到此為止

*/

testChain.addCommand(new Command() {

public boolean execute(Context context) throws Exception {

System.out.println("執(zhí)行命令2");

return true;

}

});

/**

* 加入執(zhí)行命令3

*/

testChain.addCommand(new Command() {

public boolean execute(Context context) throws Exception {

System.out.println("執(zhí)行命令3");

return false;

}

});

//執(zhí)行鏈中的命令

testChain.execute(context);

//打印鏈中的所有命令

Command[] commands=testChain.getCommands();

for(Command command:commands){

System.out.println(command.getClass());

}

}

}

** 執(zhí)行結(jié)果 **

- 執(zhí)行命令1

- 執(zhí)行命令2

- class org.apache.commons.chain.config.TestChain$1

- class org.apache.commons.chain.config.TestChain$2

- class org.apache.commons.chain.config.TestChain$3

基本對象

1. Command接口。它是Commons Chain中最重要的接口,表示在Chain中的具體某一步要執(zhí)行的命令。它只有一個方法:boolean execute(Context context)。如果返回true,那么表示Chain的處理結(jié)束,Chain中的其他命令不會被調(diào)用;返回false,則Chain會繼續(xù)調(diào)用下一個Command,直到:

[x] > Command返回true;

[x] > Command拋出異常;

[x] > Chain的末尾;

2. Context接口。它表示命令執(zhí)行的上下文,在命令間實(shí)現(xiàn)共享信息的傳遞。Context接口的父接口是Map,ContextBase實(shí)現(xiàn)了Context。對于web環(huán)境,可以使用WebContext類及其子類(FacesWebContext、PortletWebContext和ServletWebContext)。

3. Chain接口。它表示“命令鏈”,要在其中執(zhí)行的命令,需要先添加到Chain中。Chain的父接口是Command,ChainBase實(shí)現(xiàn)了它。

使用配置文件

test-config.xml

className="org.apache.commons.chain.impl.DelegatingCommand"/>

className="org.apache.commons.chain.impl.DelegatingCommand"/>

className="org.apache.commons.chain.impl.ExceptionCommand"/>

裝入配置文件

public class ConfigParserTestCase extends TestCase {

private static final String DEFAULT_XML =

"/org/apache/commons/chain/config/test-config.xml";

// ------------------------------------------------------------ Constructors

/**

* Construct a new instance of this test case.

*

* @param name Name of the test case

*/

public ConfigParserTestCase(String name) {

super(name);

}

// ------------------------------------------------------ Instance Variables

/**

*

The Catalog to contain our configured commands.

*/

protected Catalog catalog = null;

/**

*

The Context to use for execution tests.

*/

protected Context context = null;

/**

*

The ConfigParser instance under test.

*/

protected ConfigParser parser = null;

// ---------------------------------------------------- Overall Test Methods

/**

* Set up instance variables required by this test case.

*/

public void setUp() {

catalog = new CatalogBase();

context = new ContextBase();

parser = new ConfigParser();

}

/**

* Return the tests included in this test suite.

*/

public static Test suite() {

return (new TestSuite(ConfigParserTestCase.class));

}

/**

* Tear down instance variables required by this test case.

*/

public void tearDown() {

parser = null;

context = null;

catalog = null;

}

/**

執(zhí)行測試方法

**/

public void testExecute2c() throws Exception {

load(DEFAULT_XML);

try {

catalog.getCommand("Execute").execute(context);

} catch (ArithmeticException e) {

assertEquals("Correct exception id",

"3", e.getMessage());

}

checkExecuteLog("1/2/3");

}

/**

從配置文件中加載配置信息

**/

protected void load(String path) throws Exception {

parser.parse(this.getClass().getResource(path));

catalog = CatalogFactoryBase.getInstance().getCatalog();

}

}

注意:使用配置文件的話,需要使用Commons Digester。而Digester則依賴:Commons Collections、Commons Logging和Commons BeanUtils。

4. Filter接口。它的父接口是Command,它是一種特殊的Command。除了Command的execute,它還包括一個方法:boolean postprocess(Context context, Exception exception)。Commons Chain會在執(zhí)行了Filter的execute方法之后,執(zhí)行postprocess(不論Chain以何種方式結(jié)束)。Filter的執(zhí)行execute的順序與Filter出現(xiàn)在Chain中出現(xiàn)的位置一致,但是執(zhí)行postprocess順序與之相反。如:如果連續(xù)定義了filter1和filter2,那么execute的執(zhí)行順序是:filter1 -> filter2;而postprocess的執(zhí)行順序是:filter2 -> filter1。

5. Catalog接口。它是邏輯命名的Chain和Command集合。通過使用它,Command的調(diào)用者不需要了解具體實(shí)現(xiàn)Command的類名,只需要通過名字就可以獲取所需要的Command實(shí)例。

6.

的使用。配置文件的引入,使得Commons Chain的靈活性大大的提高。在實(shí)際的使用過程中,存在著同一個Command被多個Chain使用的情形。如果每次都書寫Command的類名,尤其是前面的包名特別長的情況下,是非常枯燥的。而

的作用就是為了解決這樣的麻煩。通過定義Command和Chain的別名,來簡化書寫。配置文件,可以書寫成:

className="org.apache.commons.chain.generic.LookupCommand"/>

參考:

總結(jié)

以上是生活随笔為你收集整理的java commons-chain_Apache commons chain 初探的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。