这个模式还是挺不错的
以前没有听说过,在职责链设计模式总,会用多种不同的方式来解决同一个问题,然后将他们链接在一起。当一个请求到来时,它遍历这个链直到链中的某个解决方案能够处理该请求。其中每次尝试都可以看做为一个策略,而完整的处理方式列表就是一个职责链。
看一个例子
import java.util.Iterator;
class Mail {
enum GeneralDelivery {YES, NO1, NO2, NO3, NO4, NO5}
enum Scannability {UNSCANNABLE, YES1, YES2, YES3, YES4}
enum Readability {ILLEGIBLE, YES1, YES2, YES3, YES4}
enum Address {INCORRECT, OK1, OK2, OK3, OK4, OK5, OK6}
enum ReturnAddress {MISSING, OK1, OK2, OK3, OK4, OK5}
GeneralDelivery generalDelivery;
Scannability scannability;
Readability readability;
Address address;
ReturnAddress returnAddress;
static long counter = 0;
long id = counter++;
//重写toString方法
public String toString() {
return "Mail " + id;
}
//显示详细详细
public String details() {
return toString() +
", GeneralDelivery: " + generalDelivery +
", Scannability: " + scannability +
", Readability: " + readability +
", Address: " + address +
", ReturnAddress: " + returnAddress ;
}
//创建一个随机的Mail对象,内容也随机
public static Mail randomMail() {
Mail mail = new Mail();
//调用一个Enums中的随机选取工具
mail.generalDelivery = Enums.random(GeneralDelivery.class);
mail.scannability = Enums.random(Scannability.class);
mail.readability = Enums.random(Readability.class);
mail.address = Enums.random(Address.class);
mail.returnAddress = Enums.random(ReturnAddress.class);
return mail;
}
/**
* 随机产生制度能够数量的信
* @param count 数量
* @return 以迭代器返回,可以使用for-each遍历
*/
public static Iterable<Mail> generator(final int count) {
return new Iterable<Mail>() {
int n = count;
@Override
public Iterator<Mail> iterator() {
return new Iterator<Mail>() {
@Override
public boolean hasNext() {
return n-- > 0;
}
@Override
public Mail next() {
return randomMail();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
}
public class PostOffice {
/*
* 定义了四种处理邮件的方式
* 每一种都会返回对应的值true或false
* 如果返回false表示该种方式不可行
*/
enum MailHandler {
GENERAL_DELIVERY {
@Override
boolean handle(Mail m) {
switch (m.generalDelivery) {
case YES:
System.out.println("Using general delivery for " + m);
return true;
default:
break;
}
return false;
}
},
MACHINE_SCAN {
@Override
boolean handle(Mail m) {
switch (m.scannability) {
case UNSCANNABLE:
return false;
default:
switch (m.address) {
case INCORRECT:
return false;
default:
System.out.println("Delivering " + m + " atuomatically");
return true;
}
}
}
},
VISUAL_INSPECTION {
@Override
boolean handle(Mail m) {
switch (m.readability) {
case ILLEGIBLE:
return false;
default:
switch (m.address) {
case INCORRECT:
return false;
default:
System.out.println("Delivering " + m + " normally");
return true;
}
}
}
},
RETURN_TO_SENOER {
@Override
boolean handle(Mail m) {
switch (m.returnAddress) {
case MISSING:
return false;
default:
System.out.println("Returing " + m + " to sender");
return true;
}
}
};
abstract boolean handle(Mail m);
}
/**
* 按照MailHandler中的几种方法依次处理该邮件,
* 如果有一种可以处理则返回成功
* 如果所有的方法都不能处理,判定该邮件为死信
* @param m 邮件
*/
static void handle(Mail m) {
for(MailHandler handler : MailHandler.values()) {
if(handler.handle(m)) {
return;
}
}
System.out.println(m + " is a dead letter.");
}
public static void main(String[] args) {
//随机生成10封信
for(Mail mail : Mail.generator(10)) {
System.out.println(mail.details());
handle(mail);
System.out.println("===============================");
}
}
}
输出结果
Mail 0, GeneralDelivery: NO2, Scannability: UNSCANNABLE, Readability: YES3, Address: OK1, ReturnAddress: OK1
Delivering Mail 0 normally
===============================
Mail 1, GeneralDelivery: NO5, Scannability: YES3, Readability: ILLEGIBLE, Address: OK5, ReturnAddress: OK1
Delivering Mail 1 atuomatically
===============================
Mail 2, GeneralDelivery: YES, Scannability: YES3, Readability: YES1, Address: OK1, ReturnAddress: OK5
Using general delivery for Mail 2
===============================
Mail 3, GeneralDelivery: NO4, Scannability: YES3, Readability: YES1, Address: INCORRECT, ReturnAddress: OK4
Returing Mail 3 to sender
===============================
Mail 4, GeneralDelivery: NO4, Scannability: UNSCANNABLE, Readability: YES1, Address: INCORRECT, ReturnAddress: OK2
Returing Mail 4 to sender
===============================
Mail 5, GeneralDelivery: NO3, Scannability: YES1, Readability: ILLEGIBLE, Address: OK4, ReturnAddress: OK2
Delivering Mail 5 atuomatically
===============================
Mail 6, GeneralDelivery: YES, Scannability: YES4, Readability: ILLEGIBLE, Address: OK4, ReturnAddress: OK4
Using general delivery for Mail 6
===============================
Mail 7, GeneralDelivery: YES, Scannability: YES3, Readability: YES4, Address: OK2, ReturnAddress: MISSING
Using general delivery for Mail 7
===============================
Mail 8, GeneralDelivery: NO3, Scannability: YES1, Readability: YES3, Address: INCORRECT, ReturnAddress: MISSING
Mail 8 is a dead letter.
===============================
Mail 9, GeneralDelivery: NO1, Scannability: UNSCANNABLE, Readability: YES2, Address: OK1, ReturnAddress: OK4
Delivering Mail 9 normally
===============================
看起来较为复杂,其实很简单。
就是有很多种处理信的方式,来了一封信就用这些方式依次处理,如果所有的方式都不能处理那就是死信,一旦有一种可以处理就通过。
enum MailHandler 中每一种处理方式都可以看成是一种策略,如果想增加处理方式,直接在enum MailHandler 添加即可,特别方便