设计模式之行为型3
设计模式之行为型3
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
1. 迭代器模式
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。核心:为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。
-
迭代模式结构图
![迭代模式]()
-
迭代器实现
-
Iterator迭代器抽象类
abstract class Iterator{ //用于定义得到开始对象、下一个对象、判断是否到结尾、当前对象等抽象方法, //统一接口 public abstract Object first(); public abstract Onject next(); public abstract boolean isDone(); public abstract Onject currentItem() } -
Aggregate聚集抽象类
abstract class Aggregate{ //创建迭代器 public abstract Iterator createIterator(); } -
ConcreteIterator具体迭代类,继承Iterator
class ConcreteIterator extends Iterator{ //定义具体聚集对象 private ConcreteAggregate aggregate; private int current = 0; //初始化时将具体的聚集对象传入 public ConcreteIterator(ConcreteAggregate aggregate){ this.aggregate = aggregate; } //得到聚集的第一个对象 @override public Object first(){ return aggregate[0]; } //得到聚集的下一个对象 @override public Object next(){ Object ret = null; current++; if(current < aggregate.count()){ ret = aggregate[current]; } return ret; } //判断当前是否遍历到结尾 @override public boolean isDone(){ return current >= aggregate.count ? true:false; } //返回当前的聚集对象 @override public Object currentItem(){ return aggregate[current]; } } -
ConcreteAggregate 具体聚集类,继承Aggregate
class ConcreteAggregate extend Aggregate{ private List<Object> items = new ArrayList<>(); private int index; @override public Iterator createIterator(){ return new ConcreteIterator(this); } //返回聚集个数 public int count(){ return item.size(); } //声明一个索引 public void setIndex(int index){ this.index = index; } public int getIndex(){ return index; } } -
客户端代码
static void main(String[] args){ ConcreteAggregate a = new ConcreteAggregate(); a[0] = "大鸟"; a[1] = "小菜"; a[2] = "老外"; a[3] = "小偷"; Iterator i = new ConcreteIterator(a); Object item = i.first(); while(!i.isDone){ System.out.println("请买票"+i.currentItem()); i.next(); } }
-
-
迭代器模式应用实例
编写一个程序展示一个学校的院系结构
-
类图
![image-20220730102411282]()
-
department系类
//ϵ public class Department { private String name; private String desc; public Department(String name, String desc) { super(); this.name = name; this.desc = desc; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } } -
ComputerCollegeIterator,计算机学院迭代器类
import java.util.Iterator; public class ComputerCollegeIterator implements Iterator { //这里我们需要Department 是以怎样的方式存放=>数组 Department[] departments; int position = 0; //遍历的位置 public ComputerCollegeIterator(Department[] departments) { this.departments = departments; } //判断是否还有下一个元素 @Override public boolean hasNext() { // TODO Auto-generated method stub if(position >= departments.length || departments[position] == null) { return false; }else { return true; } } @Override public Object next() { // TODO Auto-generated method stub Department department = departments[position]; position += 1; return department; } //删除的方法,默认空实现 public void remove() { } } -
InfoColleageIterator
import java.util.Iterator; import java.util.List; public class InfoColleageIterator implements Iterator { List<Department> departmentList; // 信息工程学院是以List方式存放系 int index = -1;//索引 public InfoColleageIterator(List<Department> departmentList) { this.departmentList = departmentList; } //判断list中还有没有下一个元素 @Override public boolean hasNext() { // TODO Auto-generated method stub if(index >= departmentList.size() - 1) { return false; } else { index += 1; return true; } } @Override public Object next() { // TODO Auto-generated method stub return departmentList.get(index); } //空实现remove public void remove() { } } -
College学校接口
import java.util.Iterator; public interface College { public String getName(); //增加系的方法 public void addDepartment(String name, String desc); //返回一个迭代器,遍历 public Iterator createIterator(); } -
ComputerCollege类实现College接口
import java.util.Iterator; public class ComputerCollege implements College { Department[] departments; int numOfDepartment = 0 ;// 保存当前数组的对象个数 public ComputerCollege() { departments = new Department[5]; addDepartment("Java专业", " Java专业 "); addDepartment("PHP专业", " PHP专业 "); addDepartment("大数据专业", " 大数据专业 "); } @Override public String getName() { // TODO Auto-generated method stub return "计算机学院"; } @Override public void addDepartment(String name, String desc) { // TODO Auto-generated method stub Department department = new Department(name, desc); departments[numOfDepartment] = department; numOfDepartment += 1; } @Override public Iterator createIterator() { // TODO Auto-generated method stub return new ComputerCollegeIterator(departments); } } -
InfoCollege实现College接口
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class InfoCollege implements College { List<Department> departmentList; public InfoCollege() { departmentList = new ArrayList<Department>(); addDepartment("信息安全专业", " 信息安全专业 "); addDepartment("网络安全专业", " 网络安全专业 "); addDepartment("服务器安全专业", " 服务器安全专业 "); } @Override public String getName() { // TODO Auto-generated method stub return "信息工程学院"; } @Override public void addDepartment(String name, String desc) { // TODO Auto-generated method stub Department department = new Department(name, desc); departmentList.add(department); } @Override public Iterator createIterator() { // TODO Auto-generated method stub return new InfoColleageIterator(departmentList); } } -
输出
import java.util.Iterator; import java.util.List; public class OutPutImpl { //学院集合 List<College> collegeList; public OutPutImpl(List<College> collegeList) { this.collegeList = collegeList; } //遍历所有学院,然后调用printDepartment 输出各个学院的系 public void printCollege() { //从collegeList 取出所有学院, Java 中的 List 已经实现Iterator Iterator<College> iterator = collegeList.iterator(); while(iterator.hasNext()) { //取出一个学院 College college = iterator.next(); System.out.println("=== "+college.getName() +"=====" ); printDepartment(college.createIterator()); //得到对应迭代器 } } //输出学院输出系 public void printDepartment(Iterator iterator) { while(iterator.hasNext()) { Department d = (Department)iterator.next(); System.out.println(d.getName()); } } } -
客户端
import java.util.ArrayList; import java.util.List; public class Client { public static void main(String[] args) { // TODO Auto-generated method stub //创建学院 List<College> collegeList = new ArrayList<College>(); ComputerCollege computerCollege = new ComputerCollege(); InfoCollege infoCollege = new InfoCollege(); collegeList.add(computerCollege); //collegeList.add(infoCollege); OutPutImpl outPutImpl = new OutPutImpl(collegeList); outPutImpl.printCollege(); } }
-
-
小结
优点:
- 提供统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以遍历对象了。
- 隐藏了聚合的内部结构
- 符合单一职责原则
缺点:
每个聚合对象都要一个迭代器,会生成多个迭代器,不好管理类。
2. 命令模式
命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
-
命令模式结构图
![image-20220730105718254]()
-
代码实现
-
Command类,用来声明执行操作的接口
abstract class Command{ protected Receiver receiver; public Command(Receiver receiver){ this.receiver = receiver; } public abstract void execute(); } -
ConcreteCommand类,将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现Execute。
class ConcreteCommand extends Command{ public ConcreteCommand(Receiver receiver) :super(receiver){} @override public void excute(){ receiver.action(); } } -
Invoker类,要求该命令执行这个请求
class Invoker{ private Command command; public void setCommand(Command command){ this.command = command; } public void executeCommand(){ command.execute(); } } -
Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者。
class Receiver{ public void action(){ System.out.println("执行请求!"); } } -
客户端
static void main(String[] args){ Receiver r = new Receiver(); Command c = new ConcreteCommand(r); Invoker i = new Invoker(); i.setCommand(c); i.ExecuteCommand(); }
-
-
小结
命令模式的实现需要三部分:命令部分,通知部分,执行部分。
命令部分对应不同的请求,执行部分对应不同的命令,通知部分对命令进行收集,排队,撤销,通知执行。
命令模式是为了解决请求与执行部分的紧耦合,这不方便对请求做记录,排队,操作。
命令模式的优点:1. 它能比较容易地设计一个命令队列;2. 在需要的情况下,可以较容易地将命令计入日志;3.允许接收请求的一方决定是否否决请求。
3. 责任链模式
责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
-
责任链模式结构图
![image-20220730113329213]()
-
代码实现
- Handler类,定义一个处理请示的接口
abstract class Handler{ protected Handler successor; //设置继任者 public void setSuccessor(Hander successor){ this.successor = successor; } //处理请求的抽象方法 public abstract void handleRequest(int request); }-
ConcreteHandler类,具体处理类,处理它所负责的请求,可以访问它的后继者。
//ConcreteHandler1,当请求数在0到10之间则有权处理,否则转移到下一位 class ConcreteHandler1 extends Handler{ @override public void handleRequest(int request){ if(request >= 0 && request < 10){ System.out.println("处理请求"+request); }else if(successor != null){ successor.handleRequest(request); } } } //ConcreteHandler2,当请求数在10到20之间则有权处理,否则转移到下一位 class ConcreteHandler2 extends Handler{ @override public void handleRequest(int request){ if(request >= 10 && request < 20){ System.out.println("处理请求"+request); }else if(successor != null){ successor.handleRequest(request); } } } //ConcreteHandler1,当请求数在0到10之间则有权处理,否则转移到下一位 class ConcreteHandler3 extends Handler{ @override public void handleRequest(int request){ if(request >= 20 && request < 30){ System.out.println("处理请求"+request); }else if(successor != null){ successor.handleRequest(request); } } } -
客户端代码
static void main(String[] args){ Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); Handler h3 = new ConcreteHandler3(); h1.setSuccessor(h2); h2.setSuccessor(h3); int[] requests = new int[]{2,5,3,4,7,14,25,4}; for(int r : requests){ h1.handleRequest(r); } }
-
小结
责任链模式使得当前执行者只需要知道它后继执行者即可。这种模式可避免大量的if-else判断,降低耦合,便于增删。
但注意,若链中的各个执行者都不符合处理请求的条件,请求在链的末端一定要得到合适的处理。




浙公网安备 33010602011771号