博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式 - 行为型 - 责任链模式
阅读量:6653 次
发布时间:2019-06-25

本文共 7828 字,大约阅读时间需要 26 分钟。

hot3.png

介绍

意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

何时使用:在处理消息的时候以过滤很多道。

如何解决:拦截的类都实现统一接口。

实现

实现一

创建抽象类 AbstractLogger,带有详细的日志记录级别。然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。

public abstract class AbstractLogger {	public static int INFO = 1;	public static int DEBUG = 2;	public static int ERROR = 3;	protected int level;	// 责任链中的下一个元素	protected AbstractLogger nextLogger;	public void setNextLogger(AbstractLogger nextLogger) {		this.nextLogger = nextLogger;	}	public void logMessage(int level, String message) {		if (this.level <= level) {			write(message);		}		if (nextLogger != null) {			nextLogger.logMessage(level, message);		}	}	abstract protected void write(String message);}

public class ConsoleLogger extends AbstractLogger {	public ConsoleLogger(int level) {		this.level = level;	}	[@Override](https://my.oschina.net/u/1162528)	protected void write(String message) {		System.out.println("Standard Console::Logger: " + message);	}}

public class ErrorLogger extends AbstractLogger {	public ErrorLogger(int level) {		this.level = level;	}	[@Override](https://my.oschina.net/u/1162528)	protected void write(String message) {		System.out.println("Error Console::Logger: " + message);	}}

public class FileLogger extends AbstractLogger {	public FileLogger(int level) {		this.level = level;	}	[@Override](https://my.oschina.net/u/1162528)	protected void write(String message) {		System.out.println("File::Logger: " + message);	}}

public class ChainPatternDemo {	private static AbstractLogger getChainOfLoggers() {		AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);		AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);		AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);		errorLogger.setNextLogger(fileLogger);		fileLogger.setNextLogger(consoleLogger);		return errorLogger;	}	public static void main(String[] args) {		AbstractLogger loggerChain = getChainOfLoggers();		loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");		System.out.println();				loggerChain.logMessage(AbstractLogger.DEBUG, "This is an debug level information.");		System.out.println();				loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");				System.out.println();	}}

运行结果

Standard Console::Logger: This is an information.File::Logger: This is an debug level information.Standard Console::Logger: This is an debug level information.Error Console::Logger: This is an error information.File::Logger: This is an error information.Standard Console::Logger: This is an error information.

实现二

模拟Mail邮件处理 以及 Enum 的运用来演示责任链模式

public class Enums {	private static Random rand = new Random(47);	public static 
> T random(Class
ec) { return random(ec.getEnumConstants()); } public static
T random(T[] values) { return values[rand.nextInt(values.length)]; }}

class Mail {	// The NO's lower the probability of random selection:	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++;	public String toString() {		return "Mail " + id;	}	public String details() {		return toString() + ", General Delivery: " + generalDelivery + ", Address Scanability: " + scannability				+ ", Address Readability: " + readability + ", Address Address: " + address + ", Return address: "				+ returnAddress;	}	// Generate test Mail:	public static Mail randomMail() {		Mail m = new Mail();		m.generalDelivery = Enums.random(GeneralDelivery.class);		m.scannability = Enums.random(Scannability.class);		m.readability = Enums.random(Readability.class);		m.address = Enums.random(Address.class);		m.returnAddress = Enums.random(ReturnAddress.class);		return m;	}	public static Iterable
generator(final int count) { return new Iterable
() { int n = count; public Iterator
iterator() { return new Iterator
() { public boolean hasNext() { return n-- > 0; } public Mail next() { return randomMail(); } public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; } }; }}public class PostOffice { enum MailHandler { GENERAL_DELIVERY { boolean handle(Mail m) { switch (m.generalDelivery) { case YES: System.out.println("Using general delivery for " + m); return true; default: return false; } } }, MACHINE_SCAN { 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 + " automatically"); return true; } } } }, VISUAL_INSPECTION { 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_SENDER { boolean handle(Mail m) { switch (m.returnAddress) { case MISSING: return false; default: System.out.println("Returning " + m + " to sender"); return true; } } }; abstract boolean handle(Mail 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) { for (Mail mail : Mail.generator(10)) { System.out.println(mail.details()); handle(mail); System.out.println("*****"); } }}

运行结果:

Mail 0, General Delivery: NO2, Address Scanability: UNSCANNABLE, Address Readability: YES3, Address Address: OK1, Return address: OK1Delivering Mail 0 normally*****Mail 1, General Delivery: NO5, Address Scanability: YES3, Address Readability: ILLEGIBLE, Address Address: OK5, Return address: OK1Delivering Mail 1 automatically*****Mail 2, General Delivery: YES, Address Scanability: YES3, Address Readability: YES1, Address Address: OK1, Return address: OK5Using general delivery for Mail 2*****Mail 3, General Delivery: NO4, Address Scanability: YES3, Address Readability: YES1, Address Address: INCORRECT, Return address: OK4Returning Mail 3 to sender*****Mail 4, General Delivery: NO4, Address Scanability: UNSCANNABLE, Address Readability: YES1, Address Address: INCORRECT, Return address: OK2Returning Mail 4 to sender*****Mail 5, General Delivery: NO3, Address Scanability: YES1, Address Readability: ILLEGIBLE, Address Address: OK4, Return address: OK2Delivering Mail 5 automatically*****Mail 6, General Delivery: YES, Address Scanability: YES4, Address Readability: ILLEGIBLE, Address Address: OK4, Return address: OK4Using general delivery for Mail 6*****Mail 7, General Delivery: YES, Address Scanability: YES3, Address Readability: YES4, Address Address: OK2, Return address: MISSINGUsing general delivery for Mail 7*****Mail 8, General Delivery: NO3, Address Scanability: YES1, Address Readability: YES3, Address Address: INCORRECT, Return address: MISSINGMail 8 is a dead letter*****Mail 9, General Delivery: NO1, Address Scanability: UNSCANNABLE, Address Readability: YES2, Address Address: OK1, Return address: OK4Delivering Mail 9 normally*****

参考及引用

1.《Java编程思想(第四版)》

转载于:https://my.oschina.net/jallenkwong/blog/1920534

你可能感兴趣的文章
10个很棒的学习Android 开发的网站
查看>>
SyntaxError: missing ] after element list 火狐问题
查看>>
QML用Qt.labs.settings实现保存用户设置
查看>>
异步查询json传日期格式到前台,变成了时间戳的格式
查看>>
Android长按事件和点击事件问题处理,OnItemLongClickListener和OnItemClickListener冲突问题...
查看>>
python(43):collections模块
查看>>
springMVC拦截器和过滤器总结
查看>>
CDH版本的oozie安装执行bin/oozie-setup.sh prepare-war,没生成oozie.war?
查看>>
perl 中的哈希赋值
查看>>
COCOS2D-X暂时设置竖屏,过一阵子再设置回横屏
查看>>
[Java]线程池
查看>>
Server Tomcat v7.0 Server at libra failed to start
查看>>
Java多线程(八)——join()
查看>>
HDOJ 题目3308 LCIS(线段树,区间查询,区间合并)
查看>>
Linux 设备驱动--- Poll 方法 --- Select【转】
查看>>
基于V4L2的视频驱动开发【转】
查看>>
手动操作导航控制器的子视图控制器的数组
查看>>
Spring 3整合Quartz 2实现手动设置定时任务:新增,修改,删除,暂停和恢复
查看>>
Lintcode---二叉树的锯齿形层次遍历
查看>>
Leetcode题解(5):L58/Length of Last Word
查看>>