职责链模式(Chain of Responsibility)
2018-12-03 本文已影响8人
fomin
1、概念
职责链模式为为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它,属于行为型模式。
未命名文件(6).png
2、模式结构
- 抽象处理者(Handler)角色:定义出一个处理请求的接口;如果需要,接口可以定义 出一个方法以设定和返回对下家的引用
- 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家
3、使用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
- 可动态指定一组对象处理请求
4、优缺点
优点:
- 降低耦合度。它将请求的发送者和接收者解耦
- 可简化对象的相互连接,使得对象不需要知道链的结构
- 增强给对象指派职责的灵活性,通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任
- 增加新的请求处理类很方便
缺点:
- 不能保证请求一定被接收
- 系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用
- 可能不容易观察运行时的特征,有碍于除错
5、实例
定义实体类User
public class User {
private int userId;
private String userName;
private int userPoint;
public User(int userId, String userName, int userPoint) {
this.userId = userId;
this.userName = userName;
this.userPoint = userPoint;
}
public int getUserId() {
return userId;
}
public int getUserPoint() {
return userPoint;
}
public String getUserName() {
return userName;
}
}
定义抽象Handler角色LevelHandler
public abstract class LevelHandler {
protected LevelHandler next;
public LevelHandler getNext() {
return next;
}
public void setNext(LevelHandler next) {
this.next = next;
}
public abstract void handleAction(User user, int point);
}
定义具体NormalLevel
public class NormalLevel extends LevelHandler {
private static final int needPoint = 1000;
@Override
public void handleAction(User user, int point) {
if (user.getUserPoint() + point > needPoint) {
getNext().handleAction(user, point);
} else {
// 业务逻辑
}
}
}
定义具体AdvancedLevel
public class AdvancedLevel extends LevelHandler {
private static final int needPoint = 5000;
@Override
public void handleAction(User user, int point) {
if (user.getUserPoint() + point > needPoint) {
getNext().handleAction(user, point);
} else {
// 业务逻辑
}
}
}
定义具体VIPLevel
public class VIPLevel extends LevelHandler {
private static final int needPoint = 10000;
@Override
public void handleAction(User user, int point) {
// 业务逻辑
}
}
客户端调用
NormalLevel normalLevel = new NormalLevel();
AdvancedLevel advancedLevel = new AdvancedLevel();
VIPLevel vipLevel = new VIPLevel();
normalLevel.setNext(advancedLevel);
advancedLevel.setNext(vipLevel);
normalLevel.handleAction(new User(100, "text", 1000), 1000);