行为性模式有以下几种模式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FZcwXAOB-1611137918409)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210118113313479.png)]
在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”。
编写制作豆浆的程序,说明如下:
请使用 模板方法模式 完成 (说明:因为模板方法模式,比较简单,很容易就想到这个方案,因此就直接使用,不再使用传统的方案来引出模板方法模式 )
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QjfSnjL8-1611137918412)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210118113633455.png)]
//SoyMilk 抽象类,提供模板方法
public abstract class SoyMilk {
//模板方法,定义执行该抽象类方法的模板
//使用final修饰,阻止子类对他进行重写
final void make(){
select();
if (whetherAdd()) {
add();
}
soak();
beat();
}
void select(){
System.out.println("选择上等的黄豆");
}
//添加材料方法,需要子类实现
abstract void add();
void soak(){
System.out.println("材料浸泡一段时间");
}
void beat(){
System.out.println("开始打豆浆");
}
//钩子方法,用于判断是否需要加料,默认为true,子类可以重写覆盖方法
boolean whetherAdd(){
return true;
}
}
//BlackBeanSoyMilk
public class BlackBeanSoyMilk extends SoyMilk {
@Override
void add() {
System.out.println("加入上等的黑豆");
}
}
//RedBeanSoyMilk
public class RedBeanSoyMilk extends SoyMilk {
@Override
void add() {
System.out.println("加入上好的红豆");
}
}
//PureSoyMilk
public class PureSoyMilk extends SoyMilk {
//不需要加料时,默认空实现
@Override
void add() {
}
//不需要加料,需要重写钩子方法
@Override
boolean whetherAdd() {
return false;
}
}
//Client
public class Client {
public static void main(String[] args) {
System.out.println("----------制作黑豆豆浆----------");
SoyMilk blackBeanSoyMilk = new BlackBeanSoyMilk();
blackBeanSoyMilk.make();
System.out.println("----------制作红豆豆浆----------");
SoyMilk redBeanSoyMilk = new RedBeanSoyMilk();
redBeanSoyMilk.make();
System.out.println("----------制作纯豆浆----------");
SoyMilk pureSoyMilk = new PureSoyMilk();
pureSoyMilk.make();
}
}
Spring IOC容器初始化时运用到的模板方法模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cww08abk-1611137918414)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210118152956460.png)]
看一个具体的需求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b937T3I1-1611137918416)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210118153243023.png)]
//抽象的命令类Command
public interface Command {
void execute();
void undo();
}
//接受执行者LightReceiver
public class LightReceiver{
public void on(){
System.out.println("灯打开");
}
public void off(){
System.out.println("灯关闭");
}
}
//命令实现类LightOnCommand
public class LightOnCommand implements Command {
private LightReceiver light;
public LightOnCommand(LightReceiver light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
//命令实现类LightOffCommand
public class LightOffCommand implements Command {
private LightReceiver light;
public LightOffCommand(LightReceiver light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
//空命令类NoCommand
/**
* 没有任何命令,即空执行: 用于初始化每个按钮, 当调用空命令时,对象什么都不做
* 其实,这样是一种设计模式, 可以省掉对空判断
* @author Administrator
*
*/
public class NoCommand implements Command {
@Override
public void execute() {
}
@Override
public void undo() {
}
}
//指挥者RemoteController
public class RemoteController {
private Command onCommands[];
private Command offCommands[];
private Command unDoCommand;
public RemoteController(){
onCommands=new Command[5];
offCommands=new Command[5];
for(int i=0;i<5;i++){
onCommands[i]=new NoCommand();
offCommands[i]=new NoCommand();
}
}
public void setCommand(int on,Command onCommand,Command offCommand){
this.onCommands[on]=onCommand;
this.offCommands[on]=offCommand;
}
public void clickOnButton(int on){
onCommands[on].execute();
unDoCommand=onCommands[on];
}
public void clickOffButton(int on){
offCommands[on].execute();
unDoCommand=offCommands[on];
}
public void repeal(){
if(unDoCommand!=null){
unDoCommand.undo();
}
}
}
//测试Client
public class Client {
public static void main(String[] args) {
LightReceiver lightReceiver=new LightReceiver();
LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
RemoteController remoteController=new RemoteController();
remoteController.setCommand(0,lightOnCommand,lightOffCommand);
remoteController.clickOnButton(0);
remoteController.clickOffButton(0);
remoteController.repeal();
}
}
//当我们新增一个其它家具时,只需要新增家具Receiver类,on和offCommand类就行,不需要修改指挥者类,扩展性还行。
Spring框架的JdbcTemplate就使用到了命令模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WqGJTF4J-1611137918418)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210118175248749.png)]
完成测评系统需求
将观众分为男人和女人,对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价(评价 有不同的种类,比如 成功、失败 等)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RzFDhaPY-1611137918419)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210118180247266.png)]
这里Action和Person使用了双分派模式:
所谓双分派是指不管类怎么变化,我们都能找到期望的方法运行。双分派意味着得到执行的操作取决于请求的种类和两个接收者的类型
//被访问者抽象类Person
public abstract class Person {
public abstract void accept(Action action);
}
//被访问者具体类Man
public class Man extends Person {
@Override
public void accept(Action action) {
action.getManResult(this);
}
}
//被访问者具体类Women
public class Women extends Person {
@Override
public void accept(Action action) {
action.getWomenResult(this);
}
}
//访问抽象类Action
public abstract class Action {
public abstract void getManResult(Man man);
public abstract void getWomenResult(Women women);
}
//访问具体类Success
public class Success extends Action {
@Override
public void getManResult(Man man) {
System.out.println("男人的肯定");
}
@Override
public void getWomenResult(Women women) {
System.out.println("女人的认可");
}
}
//访问具体类Fail
public class Fail extends Action {
@Override
public void getManResult(Man man) {
System.out.println("男人的摇头");
}
@Override
public void getWomenResult(Women women) {
System.out.println("女人的头疼");
}
}
//保存被访问的元素,用来允许访问者访问元素
public class ObjectStructure {
private List elements=new LinkedList<>();
public void attach(Person person){
elements.add(person);
}
public void detach(Person person){
elements.remove(person);
}
public void display(Action action){
for(Person p:elements){
p.accept(action);
}
}
}
//测试
public class Client {
public static void main(String[] args) {
ObjectStructure objectStructure=new ObjectStructure();
Man man = new Man();
objectStructure.attach(man);
objectStructure.display(new Success());
objectStructure.detach(man);
Women women=new Women();
objectStructure.attach(women);
objectStructure.display(new Fail());
}
}
//假设我们要添加一个Wait的状态类,考察Man类和Woman类的反应,由于使用了双分派,只需增加一个Action子类即可在客户端调用即可,不需要改动任何其他类的代码。
优点
缺点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6T7LegKt-1611137918420)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119111222864.png)]
编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwOuc6L9-1611137918421)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119111810315.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbWlc5CI-1611137918422)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119112058528.png)]
//系
public class Department {
private String name;
public Department(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Department{" +
"name='" + name + '\'' +
'}';
}
}
//迭代器类ArtCollegeIterator
public class ArtCollegeIterator implements Iterator {
private List<Department> departments;
private int num=-1;
public ArtCollegeIterator(List<Department> departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
if (num>=departments.size()-1){
return false;
}
num++;
return true;
}
@Override
public Object next() {
Department department = departments.get(num);
return department;
}
@Override
public void remove() {
}
}
//迭代器类ComputerCollegeIterator
public class ComputerCollegeIterator implements Iterator {
private Department departments[];//数组形式
private int num=0;
public ComputerCollegeIterator(Department[] departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
if(departments[num]!=null){
return true;
}
return false;
}
@Override
public Object next() {
Department department=departments[num];
num++;
return department;
}
@Override
public void remove() {
}
}
//学院抽象类College
public interface College {
public String getName();
public void addDepartment(String name);
public Iterator getIterator();
}
//计算机学院ComputerCollege
public class ComputerCollege implements College {
private Department departments[];
private int num=0;
public ComputerCollege() {
this.departments = new Department[5];
addDepartment("软件工程");
addDepartment("信息工程");
addDepartment("网络工程");
}
@Override
public String getName() {
return "信息学院";
}
@Override
public void addDepartment(String name) {
Department department=new Department(name);
departments[num]=department;
num++;
}
@Override
public Iterator getIterator() {
return new ComputerCollegeIterator(departments);
}
}
//艺术学院ArtCollege
public class ArtCollege implements College {
private List<Department> departments;
public ArtCollege() {
this.departments = new ArrayList<>();
addDepartment("服装工程");
addDepartment("室内设计");
addDepartment("画画工程");
}
@Override
public String getName() {
return "艺术系";
}
@Override
public void addDepartment(String name) {
departments.add(new Department(name));
}
@Override
public Iterator getIterator() {
return new ArtCollegeIterator(departments);
}
}
//输出类OutputImpl
public class OutputImpl {
private List<College> colleges;
public OutputImpl(List<College> colleges) {
this.colleges = colleges;
}
public void print(){
Iterator<College> iterator = colleges.iterator();
while (iterator.hasNext()){
College c = iterator.next();
System.out.println("--------"+c.getName()+"---------");
printDepartments(c.getIterator());
}
}
public void printDepartments(Iterator iterator){
while(iterator.hasNext()){
Department department = (Department) iterator.next();
System.out.println(department.getName());
}
}
}
//测试类
public class Client {
public static void main(String[] args) {
ComputerCollege computerCollege=new ComputerCollege();
ArtCollege artCollege=new ArtCollege();
List<College> list=new ArrayList<>();
list.add(computerCollege);
list.add(artCollege);
OutputImpl output=new OutputImpl(list);
output.print();
}
}
优点
缺点
JDK的ArrayList 集合中就使用了迭代器模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1BQCNx8-1611137918424)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119144123973.png)]
//观察者接口类
public interface Observer {
public void update(int temperature,int pressure,int humidity);
}
//被观察者(主体)接口类
public interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
//观察者具体类(多个)
public class BaiDu implements Observer {
private int temperature;
private int pressure;
private int humidity;
@Override
public void update(int temperature, int pressure, int humidity) {
this.temperature=temperature;
this.pressure=pressure;
this.humidity=humidity;
display();
}
public void display(){
System.out.println("=========百度网站==========");
System.out.println("百度网站今日温度"+this.temperature);
System.out.println("百度网站今日气压"+this.pressure);
System.out.println("百度网站今日湿度"+this.humidity);
}
}
被观察者(主体)具体类(一个)
public class WeatherData implements Subject{
private int temperature;
private int pressure;
private int humidity;
//观察者集合
private List<Observer> observerList;
public WeatherData() {
this.observerList =new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if(observerList.contains(observer)){
observerList.remove(observer);
}
}
@Override
public void notifyObserver() {
for(Observer observer:observerList){
if (observer!=null) {
observer.update(temperature, pressure, humidity);
}
}
}
public void setData(int temperature,int pressure,int humidity){
this.temperature=temperature;
this.pressure=pressure;
this.humidity=humidity;
System.out.println("----主体类天气数据更新----");
notifyObserver();
}
}
//测试
public class Client {
public static void main(String[] args) {
BaiDu baiDu=new BaiDu();
WeatherData weatherData=new WeatherData();
weatherData.registerObserver(baiDu);
weatherData.registerObserver(new WeChat());
weatherData.setData(1,2,3);
}
}
//在观察者模式下,增加一个观察者,十分方便,只需要把观察者加到主体的List就能实现
优点
缺点
jdk的Observable类就使用了观察者模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xu89kJ5P-1611137918425)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119161820420.png)]
智能家庭项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4fF3Y2I-1611137918426)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119162435313.png)]
//抽象中介类Mediator
public abstract class Mediator {
//将给中介者对象,加入到集合中
public abstract void register(String colleagueName, Colleague colleague);
//接收消息, 具体的同事对象发出
public abstract void getMessage(int stateChange, String colleagueName);
public abstract void sendMessage();
}
//具体中介类ConcreteMediator
public class ConcreteMediator extends Mediator {
//集合,放入所有的同事对象
private HashMap<String, Colleague> colleagueMap;
private HashMap<String, String> interMap;
public ConcreteMediator() {
colleagueMap = new HashMap<String, Colleague>();
interMap = new HashMap<String, String>();
}
@Override
public void register(String colleagueName, Colleague colleague) {
// TODO Auto-generated method stub
colleagueMap.put(colleagueName, colleague);
// TODO Auto-generated method stub
if (colleague instanceof Alarm) {
interMap.put("Alarm", colleagueName);
} else if (colleague instanceof CoffeeMachine) {
interMap.put("CoffeeMachine", colleagueName);
} else if (colleague instanceof TV) {
interMap.put("TV", colleagueName);
} else if (colleague instanceof Curtains) {
interMap.put("Curtains", colleagueName);
}
}
@Override
public void getMessage(int stateChange, String colleagueName) {
// TODO Auto-generated method stub
//处理闹钟发出的消息
if (colleagueMap.get(colleagueName) instanceof Alarm) {
if (stateChange == 0) {
((CoffeeMachine) (colleagueMap.get(interMap
.get("CoffeeMachine")))).on();
((TV) (colleagueMap.get(interMap.get("TV")))).startTv();
} else if (stateChange == 1) {
((TV) (colleagueMap.get(interMap.get("TV")))).stopTv();
}
} else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
((Curtains) (colleagueMap.get(interMap.get("Curtains"))))
.up();
} else if (colleagueMap.get(colleagueName) instanceof TV) {//如果TV发现消息
} else if (colleagueMap.get(colleagueName) instanceof Curtains) {
//如果是以窗帘发出的消息,这里处理...
}
}
@Override
public void sendMessage() {
}
}
//抽象同事类
public abstract class Colleague {
private String name;
private Mediator mediator;
public Colleague(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}
public Mediator getMediator(){
return this.mediator;
}
public abstract void sendMessage(int state);
}
//具体同事类
public class Alarm extends Colleague {
public Alarm(String name, Mediator mediator) {
super(name, mediator);
mediator.register("Alarm",this);
}
@Override
public void sendMessage(int state) {
this.getMediator().getMessage(state,"Alarm");
}
public void alarm(int state){
sendMessage(state);
}
}
---
public class TV extends Colleague{
public TV(String name, Mediator mediator) {
super(name, mediator);
mediator.register("TV",this);
}
@Override
public void sendMessage(int state) {
// TODO Auto-generated method stub
this.getMediator().getMessage(state,"TV");
}
public void startTv() {
// TODO Auto-generated method stub
System.out.println("It's time to StartTv!");
}
public void stopTv() {
// TODO Auto-generated method stub
System.out.println("StopTv!");
}
}
//同事类等等。。。
//测试Client
public class Client {
public static void main(String[] args) {
//创建一个中介者对象
Mediator mediator = new ConcreteMediator();
//创建Alarm 并且加入到 ConcreteMediator 对象的HashMap
Alarm alarm = new Alarm("alarm",mediator);
//创建了CoffeeMachine 对象,并 且加入到 ConcreteMediator 对象的HashMap
CoffeeMachine coffeeMachine = new CoffeeMachine(
"coffeeMachine",mediator);
//创建 Curtains , 并 且加入到 ConcreteMediator 对象的HashMap
Curtains curtains = new Curtains("curtains",mediator);
TV tV = new TV("TV",mediator);
//让闹钟发出消息
alarm.alarm(0);
coffeeMachine.on();
alarm.alarm(1);
}
}
//总结来说,就是创建一个中介类,维护所有的其它需要调用的类,类的调用通过中介指定,而不通过类与类之间的调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HW8Meas7-1611137918427)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119175428655.png)]
说明:如果希望保存多个originator对象的不同时间的状态,也可以,只需要要 HashMap
游戏角色状态恢复问题
游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kkxr7ti5-1611137918429)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119175637380.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8CTV9Jt-1611137918430)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210119175854837.png)]
//需要使用备忘录的游戏角色
public class GameRole {
private int vit;
private int def;
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
//保存到备忘录
public Memento getMemento(){
return new Memento(vit,def);
}
//返回备忘录状态
public void getInfoFromMemento(Memento memento){
this.vit=memento.getVit();
this.def=memento.getDef();
}
//显示状态
public void display(){
System.out.println("游戏角色当前的攻击力:" + this.vit + " 防御力: " + this.def);
}
}
//Memento 备忘录对象
public class Memento {
private int vit;
private int def;
public Memento(int vit, int def) {
this.vit = vit;
this.def = def;
}
public int getVit() {
return vit;
}
public int getDef() {
return def;
}
}
//CareTaker 用于保存备忘录的类
public class CareTaker {
//如果只保存一次状态
private Memento memento;
//对GameRole 保存多次状态
//private ArrayList mementos;
//对多个游戏角色保存多个状态
//private HashMap> rolesMementos;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
//测试Client
public class Client {
public static void main(String[] args) {
GameRole gameRole=new GameRole();
gameRole.setDef(100);
gameRole.setVit(100);
gameRole.display();
CareTaker careTaker=new CareTaker();
careTaker.setMemento(gameRole.getMemento());
gameRole.setVit(20);
gameRole.setVit(10);
gameRole.display();
gameRole.getInfoFromMemento(careTaker.getMemento());
gameRole.display();
}
}
这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aZyh9tGP-1611137918431)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120112618221.png)]
说明: 输入Context he TerminalExpression 信息通过Client 输入即可
通过解释器模式来实现四则运算
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6p3RBKKe-1611137918432)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120112829318.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TEr0BVqJ-1611137918433)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120113000307.png)]
/**
* 抽象类表达式,通过HashMap 键值对, 可以获取到变量的值
*
* @author Administrator
*
*/
public abstract class Expression {
// a + b - c
// 解释公式和数值, key 就是公式(表达式) 参数[a,b,c], value就是就是具体值
// HashMap {a=10, b=20}
public abstract int interpreter(HashMap<String, Integer> var);
}
/**
* 变量的解释器
* @author Administrator
*
*/
public class VarExpression extends Expression {
private String key; // key=a,key=b,key=c
public VarExpression(String key) {
this.key = key;
}
// var 就是{a=10, b=20}
// interpreter 根据 变量名称,返回对应值
@Override
public int interpreter(HashMap<String, Integer> var) {
return var.get(this.key);
}
}
/**
* 抽象运算符号解析器 这里,每个运算符号,都只和自己左右两个数字有关系,
* 但左右两个数字有可能也是一个解析的结果,无论何种类型,都是Expression类的实现类
*
* @author Administrator
*
*/
public class SymbolExpression extends Expression {
protected Expression left;
protected Expression right;
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
//因为 SymbolExpression 是让其子类来实现,因此 interpreter 是一个默认实现
@Override
public int interpreter(HashMap<String, Integer> var) {
// TODO Auto-generated method stub
return 0;
}
}
//处理加法的解释器
public class AddExpression extends SymbolExpression {
public AddExpression(Expression left, Expression right) {
super(left, right);
}
//处理相加
//var 仍然是 {a=10,b=20}..
//一会我们debug 源码,就ok
public int interpreter(HashMap<String, Integer> var) {
//super.left.interpreter(var) : 返回 left 表达式对应的值 a = 10
//super.right.interpreter(var): 返回right 表达式对应值 b = 20
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
//处理减法的解释器
public class SubExpression extends SymbolExpression {
public SubExpression(Expression left, Expression right) {
super(left, right);
}
//求出left 和 right 表达式相减后的结果
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
//计算器Calculator
public class Calculator {
// 定义表达式
private Expression expression;
// 构造函数传参,并解析
public Calculator(String expStr) { // expStr = a+b
// 安排运算先后顺序
Stack<Expression> stack = new Stack<>();
// 表达式拆分成字符数组
char[] charArray = expStr.toCharArray();// [a, +, b]
Expression left = null;
Expression right = null;
//遍历我们的字符数组, 即遍历 [a, +, b]
//针对不同的情况,做处理
for (int i = 0; i < charArray.length; i++) {
switch (charArray[i]) {
case '+': //
left = stack.pop();// 从stack取出left => "a"
right = new VarExpression(String.valueOf(charArray[++i]));// 取出右表达式 "b"
stack.push(new AddExpression(left, right));// 然后根据得到left 和 right 构建 AddExpresson加入stack
break;
case '-': //
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new SubExpression(left, right));
break;
default:
//如果是一个 Var 就创建要给 VarExpression 对象,并push到 stack
stack.push(new VarExpression(String.valueOf(charArray[i])));
break;
}
}
//当遍历完整个 charArray 数组后,stack 就得到最后Expression
this.expression = stack.pop();
}
public int run(HashMap<String, Integer> var) {
//最后将表达式a+b和 var = {a=10,b=20}
//然后传递给expression的interpreter进行解释执行
return this.expression.interpreter(var);
}
}
//client测试
public class ClientTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String expStr = getExpStr(); // a+b
HashMap<String, Integer> var = getValue(expStr);// var {a=10, b=20}
Calculator calculator = new Calculator(expStr);
System.out.println("运算结果:" + expStr + "=" + calculator.run(var));
}
// 获得表达式
public static String getExpStr() throws IOException {
System.out.print("请输入表达式:");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
// 获得值映射
public static HashMap<String, Integer> getValue(String expStr) throws IOException {
HashMap<String, Integer> map = new HashMap<>();
for (char ch : expStr.toCharArray()) {
if (ch != '+' && ch != '-') {
if (!map.containsKey(String.valueOf(ch))) {
System.out.print("请输入" + String.valueOf(ch) + "的值:");
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
}
解释器模式在Spring框架应用的源码剖析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vFxtqukE-1611137918434)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120145427991.png)]
APP抽奖活动问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8FFmbq71-1611137918436)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120145738534.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RnkEcYN0-1611137918437)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120145937404.png)]
/**
* 状态抽象类
* @author Administrator
*
*/
public abstract class State {
// 扣除积分 - 50
public abstract void deductMoney();
// 是否抽中奖品
public abstract boolean raffle();
// 发放奖品
public abstract void dispensePrize();
}
/**
* 不能抽奖状态
* @author Administrator
*
*/
public class NoRaffleState extends State {
// 初始化时传入活动引用,扣除积分后改变其状态
RaffleActivity activity;
public NoRaffleState(RaffleActivity activity) {
this.activity = activity;
}
// 当前状态可以扣积分 , 扣除后,将状态设置成可以抽奖状态
@Override
public void deductMoney() {
System.out.println("扣除50积分成功,您可以抽奖了");
activity.setState(activity.getCanRaffleState());
}
// 当前状态不能抽奖
@Override
public boolean raffle() {
System.out.println("扣了积分才能抽奖喔!");
return false;
}
// 当前状态不能发奖品
@Override
public void dispensePrize() {
System.out.println("不能发放奖品");
}
}
/**
* 可以抽奖的状态
* @author Administrator
*
*/
public class CanRaffleState extends State {
RaffleActivity activity;
public CanRaffleState(RaffleActivity activity) {
this.activity = activity;
}
//已经扣除了积分,不能再扣
@Override
public void deductMoney() {
System.out.println("已经扣取过了积分");
}
//可以抽奖, 抽完奖后,根据实际情况,改成新的状态
@Override
public boolean raffle() {
System.out.println("正在抽奖,请稍等!");
Random r = new Random();
int num = r.nextInt(10);
// 10%中奖机会
if(num == 0){
// 改变活动状态为发放奖品 context
activity.setState(activity.getDispenseState());
return true;
}else{
System.out.println("很遗憾没有抽中奖品!");
// 改变状态为不能抽奖
activity.setState(activity.getNoRafflleState());
return false;
}
}
// 不能发放奖品
@Override
public void dispensePrize() {
System.out.println("没中奖,不能发放奖品");
}
}
/**
* 发放奖品的状态
* @author Administrator
*
*/
public class DispenseState extends State {
// 初始化时传入活动引用,发放奖品后改变其状态
RaffleActivity activity;
public DispenseState(RaffleActivity activity) {
this.activity = activity;
}
//
@Override
public void deductMoney() {
System.out.println("不能扣除积分");
}
@Override
public boolean raffle() {
System.out.println("不能抽奖");
return false;
}
//发放奖品
@Override
public void dispensePrize() {
if(activity.getCount() > 0){
System.out.println("恭喜中奖了");
// 改变状态为不能抽奖
activity.setState(activity.getNoRafflleState());
}else{
System.out.println("很遗憾,奖品发送完了");
// 改变状态为奖品发送完毕, 后面我们就不可以抽奖
activity.setState(activity.getDispensOutState());
//System.out.println("抽奖活动结束");
//System.exit(0);
}
}
}
/**
* 奖品发放完毕状态
* 说明,当我们activity 改变成 DispenseOutState, 抽奖活动结束
* @author Administrator
*
*/
public class DispenseOutState extends State {
// 初始化时传入活动引用
RaffleActivity activity;
public DispenseOutState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void deductMoney() {
System.out.println("奖品发送完了,请下次再参加");
}
@Override
public boolean raffle() {
System.out.println("奖品发送完了,请下次再参加");
return false;
}
@Override
public void dispensePrize() {
System.out.println("奖品发送完了,请下次再参加");
}
}
/**
* 抽奖活动 //
*
* @author Administrator
*
*/
public class RaffleActivity {
// state 表示活动当前的状态,是变化
State state = null;
// 奖品数量
int count = 0;
// 四个属性,表示四种状态
State noRafflleState = new NoRaffleState(this);
State canRaffleState = new CanRaffleState(this);
State dispenseState = new DispenseState(this);
State dispensOutState = new DispenseOutState(this);
//构造器
//1. 初始化当前的状态为 noRafflleState(即不能抽奖的状态)
//2. 初始化奖品的数量
public RaffleActivity( int count) {
this.state = getNoRafflleState();
this.count = count;
}
//扣分, 调用当前状态的 deductMoney
public void debuctMoney(){
state.deductMoney();
}
//抽奖
public void raffle(){
// 如果当前的状态是抽奖成功
if(state.raffle()){
//领取奖品
state.dispensePrize();
}
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
//这里请大家注意,每领取一次奖品,count--
public int getCount() {
int curCount = count;
count--;
return curCount;
}
public void setCount(int count) {
this.count = count;
}
public State getNoRafflleState() {
return noRafflleState;
}
public void setNoRafflleState(State noRafflleState) {
this.noRafflleState = noRafflleState;
}
public State getCanRaffleState() {
return canRaffleState;
}
public void setCanRaffleState(State canRaffleState) {
this.canRaffleState = canRaffleState;
}
public State getDispenseState() {
return dispenseState;
}
public void setDispenseState(State dispenseState) {
this.dispenseState = dispenseState;
}
public State getDispensOutState() {
return dispensOutState;
}
public void setDispensOutState(State dispensOutState) {
this.dispensOutState = dispensOutState;
}
}
/**
* 状态模式测试类
* @author Administrator
*
*/
public class ClientTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建活动对象,奖品有1个奖品
RaffleActivity activity = new RaffleActivity(1);
// 我们连续抽300次奖
for (int i = 0; i < 30; i++) {
System.out.println("--------第" + (i + 1) + "次抽奖----------");
// 参加抽奖,第一步点击扣除积分
activity.debuctMoney();
// 第二步抽奖
activity.raffle();
}
}
}
借贷平台的订单,有审核-发布-抢单 等等 步骤,随着操作的不同,会改变订单的状态, 项目中的这个模块实现就会使用到状态模式
/**
* 状态接口
* @author Administrator
*
*/
public interface State {
/**
* 电审
*/
void checkEvent(Context context);
/**
* 电审失败
*/
void checkFailEvent(Context context);
/**
* 定价发布
*/
void makePriceEvent(Context context);
/**
* 接单
*/
void acceptOrderEvent(Context context);
/**
* 无人接单失效
*/
void notPeopleAcceptEvent(Context context);
/**
* 付款
*/
void payOrderEvent(Context context);
/**
* 接单有人支付失效
*/
void orderFailureEvent(Context context);
/**
* 反馈
*/
void feedBackEvent(Context context);
String getCurrentState();
}
public abstract class AbstractState implements State {
protected static final RuntimeException EXCEPTION = new RuntimeException("操作流程不允许");
//抽象类,默认实现了 State 接口的所有方法
//该类的所有方法,其子类(具体的状态类),可以有选择的进行重写
@Override
public void checkEvent(Context context) {
throw EXCEPTION;
}
@Override
public void checkFailEvent(Context context) {
throw EXCEPTION;
}
@Override
public void makePriceEvent(Context context) {
throw EXCEPTION;
}
@Override
public void acceptOrderEvent(Context context) {
throw EXCEPTION;
}
@Override
public void notPeopleAcceptEvent(Context context) {
throw EXCEPTION;
}
@Override
public void payOrderEvent(Context context) {
throw EXCEPTION;
}
@Override
public void orderFailureEvent(Context context) {
throw EXCEPTION;
}
@Override
public void feedBackEvent(Context context) {
throw EXCEPTION;
}
}
//各种具体状态类
class FeedBackState extends AbstractState {
@Override
public String getCurrentState() {
return StateEnum.FEED_BACKED.getValue();
}
}
class GenerateState extends AbstractState {
@Override
public void checkEvent(Context context) {
context.setState(new ReviewState());
}
@Override
public void checkFailEvent(Context context) {
context.setState(new FeedBackState());
}
@Override
public String getCurrentState() {
return StateEnum.GENERATE.getValue();
}
}
class NotPayState extends AbstractState {
@Override
public void payOrderEvent(Context context) {
context.setState(new PaidState());
}
@Override
public void feedBackEvent(Context context) {
context.setState(new FeedBackState());
}
@Override
public String getCurrentState() {
return StateEnum.NOT_PAY.getValue();
}
}
class PaidState extends AbstractState {
@Override
public void feedBackEvent(Context context) {
context.setState(new FeedBackState());
}
@Override
public String getCurrentState() {
return StateEnum.PAID.getValue();
}
}
class PublishState extends AbstractState {
@Override
public void acceptOrderEvent(Context context) {
//把当前状态设置为 NotPayState。。。
//至于应该变成哪个状态,有流程图来决定
context.setState(new NotPayState());
}
@Override
public void notPeopleAcceptEvent(Context context) {
context.setState(new FeedBackState());
}
@Override
public String getCurrentState() {
return StateEnum.PUBLISHED.getValue();
}
}
class ReviewState extends AbstractState {
@Override
public void makePriceEvent(Context context) {
context.setState(new PublishState());
}
@Override
public String getCurrentState() {
return StateEnum.REVIEWED.getValue();
}
}
/**
* 状态枚举类
* @author Administrator
*
*/
public enum StateEnum {
//订单生成
GENERATE(1, "GENERATE"),
//已审核
REVIEWED(2, "REVIEWED"),
//已发布
PUBLISHED(3, "PUBLISHED"),
//待付款
NOT_PAY(4, "NOT_PAY"),
//已付款
PAID(5, "PAID"),
//已完结
FEED_BACKED(6, "FEED_BACKED");
private int key;
private String value;
StateEnum(int key, String value) {
this.key = key;
this.value = value;
}
public int getKey() {return key;}
public String getValue() {return value;}
}
//环境上下文
public class Context extends AbstractState{
//当前的状态 state, 根据我们的业务流程处理,不停的变化
private State state;
@Override
public void checkEvent(Context context) {
state.checkEvent(this);
getCurrentState();
}
@Override
public void checkFailEvent(Context context) {
state.checkFailEvent(this);
getCurrentState();
}
@Override
public void makePriceEvent(Context context) {
state.makePriceEvent(this);
getCurrentState();
}
@Override
public void acceptOrderEvent(Context context) {
state.acceptOrderEvent(this);
getCurrentState();
}
@Override
public void notPeopleAcceptEvent(Context context) {
state.notPeopleAcceptEvent(this);
getCurrentState();
}
@Override
public void payOrderEvent(Context context) {
state.payOrderEvent(this);
getCurrentState();
}
@Override
public void orderFailureEvent(Context context) {
state.orderFailureEvent(this);
getCurrentState();
}
@Override
public void feedBackEvent(Context context) {
state.feedBackEvent(this);
getCurrentState();
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
@Override
public String getCurrentState() {
System.out.println("当前状态 : " + state.getCurrentState());
return state.getCurrentState();
}
}
/**测试类*/
public class ClientTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建context 对象
Context context = new Context();
//将当前状态设置为 PublishState
context.setState(new PublishState());
System.out.println(context.getCurrentState());
// //publish --> not pay
context.acceptOrderEvent(context);
// //not pay --> paid
context.payOrderEvent(context);
// // 失败, 检测失败时,会抛出异常
// try {
// context.checkFailEvent(context);
// System.out.println("流程正常..");
// } catch (Exception e) {
// // TODO: handle exception
// System.out.println(e.getMessage());
// }
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l9UbZRek-1611137918439)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120162310483.png)]
从上图可以看到,客户context 有成员变量strategy或者其他的策略接口,至于需要使用到哪个策略,我们可以在构造器中指定
编写鸭子项目,具体要求如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uv1v9Bu-1611137918440)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120162444357.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qDBHC6G3-1611137918441)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120162629683.png)]
//FlyBehavior策略接口
public interface FlyBehavior {
void fly();
}
//FlyBehavior策略具体类GoodFlyBehavior
public class GoodFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("此鸭子飞得很牛");
}
}
//FlyBehavior策略具体类NoFlyBehavior
public class NoFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("此鸭不会飞");
}
}
/FlyBehavior策略具体类BadFlyBehavior
public class BadFlyBehavior implements FlyBehavior {
@Override
public void fly() {
System.out.println("此鸭子飞得一般啊");
}
}
//QuackBehavior策略接口
public interface QuackBehavior {
void quack();
}
//QuackBehavior策略具体类GoodQuackBehavior
public class GoodQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("此鸭子叫:呀呀呀");
}
}
//QuackBehavior策略具体类NoQuackBehavior
public class NoQuackBehavior implements QuackBehavior {
@Override
public void quack() {
System.out.println("此鸭子不会叫啊");
}
}
//duck抽象类,维护了策略类
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
public abstract void display();
public void swim(){
System.out.println("鸭子会游泳");
}
public void quack(){
if(quackBehavior!=null){
quackBehavior.quack();
}
}
public void fly(){
if(flyBehavior!=null){
flyBehavior.fly();
}
}
}
//duck的具体类WildDuck
public class WildDuck extends Duck {
public WildDuck(){
flyBehavior=new GoodFlyBehavior();
quackBehavior=new GoodQuackBehavior();
}
@Override
public void display() {
System.out.println("野生鸭子");
}
}
//duck的具体类ToyDuck
public class ToyDuck extends Duck {
public ToyDuck(){
flyBehavior=new NoFlyBehavior();
quackBehavior=new NoQuackBehavior();
}
@Override
public void display() {
System.out.println("玩具鸭鸭鸭");
}
}
//duck的具体类PekingDuck
public class PekingDuck extends Duck {
public PekingDuck(){
flyBehavior=new BadFlyBehavior();
quackBehavior=new NoQuackBehavior();
}
@Override
public void display() {
System.out.println("北京鸭");
}
}
//client测试
public class Client {
public static void main(String[] args) {
ToyDuck toyDuck=new ToyDuck();
toyDuck.quack();
toyDuck.fly();
toyDuck.swim();
PekingDuck pekingDuck=new PekingDuck();
pekingDuck.quack();
pekingDuck.fly();
}
}
JDK的 Arrays 的Comparator就使用了策略模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y0SaOsDp-1611137918443)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120174925419.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WrNRaz62-1611137918443)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120175010204.png)]
编写程序完成学校OA系统的采购审批项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JibPXrw6-1611137918444)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210120175251716.png)]
//抽象的责任链Approver
public abstract class Approver {
Approver approver;
String name;
public Approver(String name) {
// TODO Auto-generated constructor stub
this.name = name;
}
//下一个处理者
public void setApprover(Approver approver) {
this.approver = approver;
}
//处理审批请求的方法,得到一个请求, 处理是子类完成,因此该方法做成抽象
public abstract void processRequest(PurchaseRequest purchaseRequest);
}
//具体的责任链DepartmentApprover
public class DepartmentApprover extends Approver{
public DepartmentApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
// TODO Auto-generated method stub
if(purchaseRequest.getPrice() <= 5000) {
System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
}else {
approver.processRequest(purchaseRequest);
}
}
}
//具体的责任链CollegeApprover
public class CollegeApprover extends Approver{
public CollegeApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
// TODO Auto-generated method stub
if(purchaseRequest.getPrice() < 5000 && purchaseRequest.getPrice() <= 10000) {
System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
}else {
approver.processRequest(purchaseRequest);
}
}
}
//具体的责任链ViceSchoolMasterApprover
public class ViceSchoolMasterApprover extends Approver {
public ViceSchoolMasterApprover(String name) {
// TODO Auto-generated constructor stub
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
// TODO Auto-generated method stub
if(purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {
System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
}else {
approver.processRequest(purchaseRequest);
}
}
}
//具体的责任链SchoolMasterApprover
public class SchoolMasterApprover extends Approver {
public SchoolMasterApprover(String name) {
// TODO Auto-generated constructor stub
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
// TODO Auto-generated method stub
if(purchaseRequest.getPrice() > 30000) {
System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
}else {
approver.processRequest(purchaseRequest);
}
}
}
//请求对象
public class PurchaseRequest {
private int type = 0; //请求类型
private float price = 0.0f; //请求金额
private int id = 0;
//构造器
public PurchaseRequest(int type, float price, int id) {
this.type = type;
this.price = price;
this.id = id;
}
public int getType() {
return type;
}
public float getPrice() {
return price;
}
public int getId() {
return id;
}
}
//client调用
public class Client {
public static void main(String[] args) {
PurchaseRequest purchaseRequest=new PurchaseRequest(1,3000,1);
DepartmentApprover departmentApprover=new DepartmentApprover("黄老师");
CollegeApprover collegeApprover=new CollegeApprover("李主任");
ViceSchoolMasterApprover viceSchoolMasterApprover=new ViceSchoolMasterApprover("陈副校长");
SchoolMasterApprover schoolMasterApprover=new SchoolMasterApprover("冯校长");
departmentApprover.setApprover(collegeApprover);
collegeApprover.setApprover(viceSchoolMasterApprover);
viceSchoolMasterApprover.setApprover(schoolMasterApprover);
schoolMasterApprover.setApprover(departmentApprover);//形成闭环
departmentApprover.processRequest(purchaseRequest);
}
}
参考资料来源:www.atguigu.com
[参考资料来源][www.atguigu.com]
chaseRequest purchaseRequest) {
// TODO Auto-generated method stub
if(purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {
System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
}else {
approver.processRequest(purchaseRequest);
}
}
}
//具体的责任链SchoolMasterApprover
public class SchoolMasterApprover extends Approver {
public SchoolMasterApprover(String name) {
// TODO Auto-generated constructor stub
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
// TODO Auto-generated method stub
if(purchaseRequest.getPrice() > 30000) {
System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
}else {
approver.processRequest(purchaseRequest);
}
}
}
//请求对象
public class PurchaseRequest {
private int type = 0; //请求类型
private float price = 0.0f; //请求金额
private int id = 0;
//构造器
public PurchaseRequest(int type, float price, int id) {
this.type = type;
this.price = price;
this.id = id;
}
public int getType() {
return type;
}
public float getPrice() {
return price;
}
public int getId() {
return id;
}
}
//client调用
public class Client {
public static void main(String[] args) {
PurchaseRequest purchaseRequest=new PurchaseRequest(1,3000,1);
DepartmentApprover departmentApprover=new DepartmentApprover(“黄老师”);
CollegeApprover collegeApprover=new CollegeApprover(“李主任”);
ViceSchoolMasterApprover viceSchoolMasterApprover=new ViceSchoolMasterApprover(“陈副校长”);
SchoolMasterApprover schoolMasterApprover=new SchoolMasterApprover(“冯校长”);
departmentApprover.setApprover(collegeApprover);
collegeApprover.setApprover(viceSchoolMasterApprover);
viceSchoolMasterApprover.setApprover(schoolMasterApprover);
schoolMasterApprover.setApprover(departmentApprover);//形成闭环
departmentApprover.processRequest(purchaseRequest);
}
}
### 优缺点
- 将请求和处理分开,实现解耦,提高系统的灵活性
- 简化了对象,使对象不需要知道链的结构
- 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置一个最大节点数量,在setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
- 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂
- 最佳应用场景:有多个对象可以处理同一个请求时,比如:多级请求、请假/加薪等审批流程、Java Web中Tomcat对Encoding的处理、拦截器
---
## 参考资料地址说明
参考资料来源:www.atguigu.com
[参考资料来源][www.atguigu.com]
如若侵权,请联系删除