ps:本文系转载文章,阅读原文可获取源码,文章末尾有原文连接编程
ps:这一篇是写迭代器模式、责任链模式和命令模式架构
一、迭代器模式ide
提供一个对象来顺序访问聚合对象中的一堆数据,同时也隐藏聚合对象的内部表示;Java 中的 Collection、List、Set、Map 等就用到了迭代器模式。测试
迭代器模式具备如下几种角色:this
(1)抽象聚合角色:建立迭代器对象的接口,通常含有添加、删除聚合对象等方法。设计
(2)具体聚合角色:实现抽象聚合角色,获得一个具体迭代器的对象。日志
(3)抽象迭代器角色:遍历聚合元素的接口或者抽象类,通常含 hasNext 等方法。code
(4)具体迭代器角色:实现抽象迭代器角色中所定义的抽象方法,并保持迭代过程当中的游标位置。对象
下面用代码举个例子:继承
(1)抽象迭代器角色,新建一个 MyIterator接口:
public interface MyIterator {
public void first(); public void next(); public boolean hasNext(); public boolean isFirst(); public boolean isLast(); public Object getCurrentObject();
}
(2)具体迭代器角色,新建一个 ConcreteIterator 类并实现 MyIterator接口:
public class ConcreteIterator implements MyIterator{
private int cursor;
private WeakReference<List<Object>> wr;
public ConcreteIterator(List<Object> list) {
wr = new WeakReference<List<Object>>(list);
}
@Override
public void first() {
cursor = 0;
}
@Override
public void next() {
if (cursor < size()) { cursor++; }
}
private int size() {
return wr.get().size();
}
@Override
public boolean hasNext() {
if (cursor < size()) { return true; } return false;
}
@Override
public boolean isFirst() {
return cursor == 0?true:false;
}
@Override
public boolean isLast() {
return cursor == (size()-1)?true:false;
}
@Override
public Object getCurrentObject() {
return wr.get().get(cursor);
}
}
(3)抽象聚合角色,新建一个 IAggregate接口:
public interface IAggregate {
public void addObject(Object object);
public void removeObject(Object object);
public MyIterator createIterator();
}
(4)具体聚合角色,新建一个 ConcreteMyAggregate 类并实现 IAggregate接口:
public class ConcreteMyAggregate implements IAggregate{
private List<Object> list = new ArrayList<Object>(); @Override public void addObject(Object object) { this.list.add(object); } @Override public void removeObject(Object object) { this.list.remove(object); } @Override public MyIterator createIterator() { return new ConcreteIterator(list); }
}
(5)客户端进行调用测试:
IAggregate aggregate = new ConcreteMyAggregate();
aggregate.addObject("公众号小二玩编程");
aggregate.addObject("bb");
aggregate.addObject("cc");
aggregate.addObject("dd");
MyIterator iterator = aggregate.createIterator();
while (iterator.hasNext()) {
String msg = "遍历数据----" + iterator.getCurrentObject(); System.out.println(msg); iterator.next();
}
日志打印以下所示:
图片
首先建立一个具体的聚合角色 ConcreteMyAggregate 实例并向上转型赋值给抽象聚合角色 IAggregate,经过聚合角色 aggregate 添加数据并建立一个具体的迭代器角色 ConcreteIterator 实例并向上转型赋值给抽象迭代器角色 MyIterator,经过迭代器模式对 iterator 的数据进行遍历。
迭代器模式能够访问一个隐藏内部表示的聚合对象的内容,遍历数据由迭代器来实现,在代码上必定程度简化了聚合类;它能够用不一样方式访问一个聚合,也能够访问自定义迭代器子类的数据;运用了封装性,为不一样的具体聚合类提供一个统一的接口;可是新增一个具体聚合类或者具体迭代器类,在必定程度上使用可能会复杂。
二、责任链模式
把全部请求的处理者经过前一对象的属性引用下一个对象而造成一条链,当有请求时,请求沿着这条链进行传递,直到有条件知足时就会有对象处理它。
责任链模式包含如下角色:
(1)抽象处理者角色:定义出一个处理请求的接口或者抽象类,它必须包含一个处理请求的抽象方法,最好再多写2个方法,用于设置引用下一个对象和返回下一个对象。
(2)具体处理者角色:重写抽象处理者角色处理请求的抽象方法,在该方法中进行条件筛选,符合条件就进行出现,不然将请求传给引用的下一个对象进行处理。
下面咱们举个例子,某一个公司的请假流程,请假少于3天则由主管审批,请假大于等于3天小于10天就由副经理审批,请假大于等于10天小于30天由总经理审批;假设张三是主管,李四是副经理,王五是总经理,张三的领导是李四,李四的领导是王五;用代码实现一下:
(1)抽象处理者角色,新建一个抽象类 Leader:
public abstract class Leader {
protected String name;
protected Leader nextLeader;
public Leader(String name) {
super(); this.name = name;
}
public Leader getNextLeader() {
return nextLeader;
}
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
public abstract void handleRequest(LeaveRequest l);
}
(2)具体处理者角色,新建一个 Director 类并继承 Leader:
public class Director extends Leader{
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest l) {
if (l.getDay() < 3) { System.out.println("员工:" +l.getName() + ",请假天数:" + l.getDay() + ",理由" + l.getReason()); System.out.println("主任:" + this.name + "审批经过"); } else { if (this.getNextLeader() != null) { this.getNextLeader().handleRequest(l); } }
}
}
(3)具体处理者角色,新建一个 Manager 类并继承 Leader:
public class Manager extends Leader{
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest l) {
if (l.getDay() < 10) { System.out.println("员工:" +l.getName() + ",请假天数:" + l.getDay() + ",理由" + l.getReason()); System.out.println("经理:" + this.name + "审批经过"); } else { if (this.getNextLeader() != null) { this.getNextLeader().handleRequest(l); } }
}
}
(4)具体处理者角色,新建一个 GaneralManager 类并继承 Leader:
public class GaneralManager extends Leader{
public GaneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest l) {
if (l.getDay() < 30) { System.out.println("员工:" +l.getName() + ",请假天数:" + l.getDay() + ",理由" + l.getReason()); System.out.println("总经理:" + this.name + "审批经过"); } else { System.out.println("你离职吧"); }
}
}
(5)客户端进行测试调用:
Leader a = new Director("张三"); Leader b = new Manager("李四"); Leader c = new GaneralManager("王五"); a.setNextLeader(b); b.setNextLeader(c); LeaveRequest lr = new LeaveRequest("小二", 16, "娶老婆"); LeaveRequest lr2 = new LeaveRequest("小六", 31, "去相亲"); a.handleRequest(lr); a.handleRequest(lr2);
日志打印以下所示:
图片
“把全部请求的处理者经过前一对象的属性引用下一个对象而造成一条链”这句话在这个案例中是这样理解的,a 的 Leader 属性引用的是 b,b 的 Leader 属性引用的是 c;有一个员工“小二”请假16天,a 和 b 都审批不了,因此交给 c 审批,员工“小六”也是同样的道理。
责任链模式下降了对象之间的耦合度,加强了系统的可扩展性,加强了给对象指派职责的灵活性,责任链简化了对象之间的链接,分担了责任;可是它不能保证每一个请求必定被处理,若是是比较长的职责链,请求的处理也许涉及多个处理对象,客户端这边要理清责任链的关系,给程序增长了必定的复杂性。
三、命令模式
将一个执行请求封装为一个对象,目的是为了发出请求的责任和执行请求的责任分开来,它们之间经过命令对象进行通讯,这样就更好的对命令对象进行管理等。
命令模式包含如下几个角色:
(1)抽象命令类角色:定义一个执行命令的接口,包含了一个执行命令的抽象方法 。
(2)具体命令类角色:抽象命令类的子类也是具体实现类,它内部引用接收者角色,它的实现方法调用接收者角色执行请求的方法。
(3)接收者角色:是具体命令对象业务的真正实现者。
(4)请求者角色:请求的发送者,经过访问命令对象来执行相关请求,间接的访问接收者。
下面用代码举个例子:
(1)抽象命令类角色,写一个 Command 接口:
public interface Command {
public void execute();
}
(2)接收者角色,写一个 Receiver 类:
public class Receiver {
public void ation() { System.out.println("Receiver.action"); }
}
(3)具体命令类角色,写一个 ConcreteCommand 类并实现 Command 接口:
class ConcreteCommand implements Command {
private Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { receiver.ation(); }
}
(4)请求者角色,写一个 Invoke 类:
public class Invoke {
private Command command;
public Invoke(Command command) {
this.command = command;
}
public void call() {
command.execute();
}
}
(5)客户端进行测试调用:
Command command = new ConcreteCommand(new Receiver()); Invoke invoke = new Invoke(command); invoke.call();
日志打印以下所示:
图片
在这里 ConcreteCommand 是具体命令类角色对象,它封装了接收类角色对象 Receiver;Invoke 是请求者角色对象,它封装了命令类对象 Command;当 Invoke 发出请求时(调用 call 方法),它的 call 方法调用了 Command 的 execute 方法,而 Command 的 execute 方法又调用了 Receiver 的 ation 方法。
命令模式能够下降对象之间的耦合度,新的命令也很容易地加入到系统中,能够很容易地设计一个组合命令,调用同一接口命令的方法能够实现不一样的功能 ;可是极可能产生大量具体的命令类,以命令的形式进行架构、解耦请求和实现,引入了额外的类型结构,在理解上添加了必定的难度。