设计模式扫荡-行为型模式-责任链、命令、迭代器、备忘录、观察者、状态、策略、模板、访问者
文章目录
”行为型设计模式特别关注对象之间的通信。“
责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链条。这种模式给予请求的类型,对请求的发送者和接收者进行解耦
职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
责任链模式意图避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止
需求:
前端应用的消息,在经过后台服务器到最终入库之间,需要进行一系列的处理、每个处理都是独立的且都有自己的责任!如何优雅的创建这个过程?
可以借鉴平常开发中的过滤器/拦截器机制!
定义过滤器接口于消息对象:
//定义过滤器接口
interface Filter {
boolean doFilter(Msg m);
}
class Msg {
//消息名称
String name;
//消息串
String msg;
// setter getter 略...
// toString() 略
}
每个责任都继承Filter接口并实现自己的职责:
//职责:防止前端输入html代码
class HTMLFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMsg();
r = r.replace('<', '[');
r = r.replace('>', ']');
m.setMsg(r);
return true;
}
}
//职责: 敏感词筛选
class SensitiveFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMsg();
r = r.replaceAll("996", "955");
m.setMsg(r);
return false;
}
}
// ... 其他职责类
}
创建过滤链条:
//创建过滤链条 并实现Filter接口
class FilterChain implements Filter {
//一对多聚合Filter
private List<Filter> filters = new ArrayList<>();
//为职责链添加新的职责
public FilterChain add(Filter f) {
filters.add(f);
return this;
}
//职责链发挥作用
public boolean doFilter(Msg m) {
//任何一关过不去,整个过滤都会失败
for(Filter f : filters) {
if(!f.doFilter(m)) return false;
}
return true;
}
}
优点:
1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。
缺点:
1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。
命令模式(Command Pattern)
命令模式主要是对命令的封装,常见命令有如undo(撤回)、copy复制…
需求:对一个字符串,实现copy、delete、insert命令、且都支持撤回操作
//命令执行所针对的对象
public class Content {
String msg = "hello everybody ";
}
//命令接口/抽象类 [以下统称接口]
public abstract class Command {
public abstract void doit(); //exec run
public abstract void undo();
}
//复制命令,实现命令接口
public class CopyCommand extends Command {
//一比一聚合一个要操作的对象
Content c;
public CopyCommand(Content c) {
this.c = c;
}
@Override
public void doit() {
c.msg = c.msg + c.msg;
}
@Override
public void undo() {
c.msg = c.msg.substring(0, c.msg.length()/2);
}
}
//删除命令,实现命令接口
public class DeleteCommand extends Command {
//一比一聚合一个要操作的对象
Content c;
//要删除的字段
String deleted;
public DeleteCommand(Content c) {
this.c = c;
}
@Override
public void doit() {
//一次删除五个长度的字段 且所删除的字段要在对象内进行保留 方便undo
deleted = c.msg.substring(0, 5);
c.msg = c.msg.substring(5, c.msg.