行为型模式用于控制对象的行为。

  • 状态模式:将对象的状态抽象为一个类,是对if switch等状态判断的代替,Context类、State接口及其具体类。
  • 备忘录模式:获取对象状态没在对象之外保存状态,状态恢复,白箱和黑箱,宽、窄接口,私有内部类。
  • 策略模式:把算法的实现单独抽出一个类,对if switch等分支语句的替换,封装算法,并且使他们可以相互特换。
  • 调停者模式:一组对象关系错综复杂,加入调停者,各个对象只要跟调停者打交道。
  • 模板方法模式:父类定义模板方法和固定顺序,子类继承并重写模板方法。
  • 解释器模式:语言解释执行,可以将语言中的句子表示为一个抽象语法树,循环递归。

1.状态模式State

状态模式允许一个对象在其内部状态改变时,更改它的行为,这使得对象看起来就像是修改了它的类一样。
状态模式的结构要点是将状态抽象为单独的类层次,用环境类聚合状态类,当调用与状态相关的方法时,环境对象会将其委托给状态对象。
  1.Context(环境):上下文类,这个实例可以定义当前包含的状态。
  2.State(状态):定义一个接口以封装与Context的一个特定状态相关的行为。
  3.ConcreteState(具体状态):每一子类实现一个与Context的一个状态相关的行为。
实现

class Context {  //环境private State _state; //维护一个当前的状态实例public Context(State state) {_state = state;}public void request() { //状态执行请求操作,由客户调用if (_state != null) {_state.handle(this);}}public void changeState(State s) { //切换状态if (_state != null) {_state = null;}_state = s;}
}interface State {  //状态接口public void handle(Context ctx);
}class ConcreteStateA implements State { //具体状态类@Overridepublic void handle(Context ctx) { //完成本状态的行为,然后切换到下一状态System.out.println("handle by ConcreteStateA");if (ctx != null) { //切换到下一状态:切换工作转发给上下文Context来完成ctx.changeState(new ConcreteStateB());}}
}class ConcreteStateB implements State {@Overridepublic void handle(Context ctx) {System.out.println("handle by ConcreteStateB");if (ctx != null) {ctx.changeState(new ConcreteStateA());}}
}public class StateClient {public static void main(String[] args) {State state = new ConcreteStateA();Context context = new Context(state);context.request(); //内部会把状态转发给具体状态类,它完成状态的行为后,//又会返回到Context,以进行状态切换        context.request();context.request();context.request();}
}

2.备忘录模式Memento

备忘录模式可以在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后再需要时就将该对象恢复到原先保存的状态。
备忘录模式可以将一个对象的状态外部化,并可以根据需要在适当的时候恢复状态。有两种实现方式:白箱实现和黑箱实现。
白箱实现:
  1.Memento备忘录角色:(1)将原发器对象的内部状态存储起来,备忘录可以根据原发器对象的判断来决定存储多少原发器对象的内部状态。(2)备忘录可以保护其内容不被原发器对象之外的任何对象所读取。
  2.Originator原发器角色:(1)创建一个含有当前内部状态的备忘录对象;(2)使用备忘录对象存储其内部状态;
  3.Caretaker负责人角色:(1)负责保存备忘录对象;(2)不检查备忘录对象的内容;
实现:

//Memento备忘录角色
public class Memento{private String state;public String getState(){ return state;}public void setState(String state){this.state = state;}public Memento(String state){super();this.state = state;}
}
//原发器类
public class Originator{private String state;public String getState(){return state;}public void setState(String state){this.state= state;}//创建备忘录对象public Memento createMemento(){return new Memento(this.state);}//恢复状态public void setMemento(Memento memento){this.state = memento.getState();}
}
//负责人类
public class Caretaker{private Memento memento;//保存备忘录对象public void saveMemento(Memento memento){this.memento = memento; }//取回备忘录对象public Memento retrieveMemento(){ return memento;}
}
//客户端代码
public class Client{//创建原发器、负责人public static void main(String[] args){Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState("初始状态");System.out.print("当前状态"+originator.getState());System.out.print("保存当前状态");caretaker.saveMemento(originator.createMemento());System.out.print("设置新状态");originator.setState("新状态");System.out.print("当前状态"+originator.getState());System.out.print("恢复原状态");originator.setMemento(caretaker.retriveMemento());System.out.print("当前状态"+originator.getState());}
}

白箱备忘录中,备忘录类可以被任何对象访问,宽接口和窄接口的问题,由黑箱模式解决。
黑箱模式可以将备忘录类设置为对原生器类开放宽接口,对负责人类提供窄接口。
定义私有内部类,外部无法访问,实现窄接口。将备忘录类定义为原发器类的内部类,可以保证他们之间能够互相访问各自的私有成员,实现宽接口。
实现

//备忘录接口,声明式接口,无需定义任何方法
public interface IMenmento{}
//原发器类
public class Originator{private String state;public String getState(){ return state;}public void setState(Stirng state){this.state = state;}//创建备忘录对象public IMemento createMemento(){return this.new Memento(this.state);}//恢复状态public void setMemento(IMemento memento){this.state = ((IMemento)memento).getState();}//备忘录,内部类private class Memento implements IMemento{private String state;public String getState(){ return state;}public void setState(String state){this.state = state;}public Memento(String state){super(); this.state = state;}}
}
//负责人类
public class Caretaker{private IMemento memento;//保存备忘录对象public void saveMemento(IMemento memento){this.memento = memento; }//取回备忘录对象public IMemento retrieveMemento(){ return memento;}
}
//客户端代码
public class Client{//创建原发器、负责人public static void main(String[] args){Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState("初始状态");System.out.print("当前状态"+originator.getState());System.out.print("保存当前状态");caretaker.saveMemento(originator.createMemento());System.out.print("设置新状态");originator.setState("新状态");System.out.print("当前状态"+originator.getState());System.out.print("恢复原状态");originator.setMemento(caretaker.retriveMemento());System.out.print("当前状态"+originator.getState());}
}

可以与命令模式相组合,实现undo,redo等命令。
在web应用中,Session和Cookie实现备忘录模式。

3.策略模式

策略模式目的是定义一系列算法,把他们一个个封装起来,并且使他们可以相互替换,从而使得算法可以独立于使用它的客户而发生变化。
  1.环境角色Context:拥有一个策略角色的引用;也叫上下文;
  2.抽象策略角色Strategy:这是一个抽象角色,通常由一个接口或者抽象类来实现。
  3.具体策略角色: 包装了相应的算法和行为。
  4.客户端:使用Context和具体的策略对象进行操作。
实现

interface DatabaseStrategy { //Strategy:抽象策略public void process();
}class MysqlDBStrategy implements DatabaseStrategy { //具体策略@Overridepublic void process() {System.out.println("处理Mysql数据库连接");}
}class OracleDBStrategy implements DatabaseStrategy {@Overridepublic void process() {System.out.println("处理Oracle数据库连接");}
}class DataBaseManager { //Context角色public void process(DatabaseStrategy dbStrategy) {dbStrategy.process();}
}public class StrategyClient {public static void main(String[] args) {MysqlDBStrategy mysql = new MysqlDBStrategy();DataBaseManager manager = new DataBaseManager();manager.process(mysql);OracleDBStrategy oracle = new OracleDBStrategy();manager.process(oracle);}
}

4.调停者模式Mediator

调停者模式定义了一个可以封装一组对象之间的相互影响的行为的对象,这样就可以使用松耦合的方式联系一组对象,避免对象之间相互显示地直接引用,从而当改变了某些对象之间的关系时,就可以不影响其他对象了。
相当于在个团队之间加上一个经理,负责管理所有队员的沟通,使同事关系变得简洁。
  1.IMediator调停者接口:用于与各个同事IColleague对象通信;
  2.MediatorImpl具体调停者:负责封装各个同事对象之间的协调关系并维护各个同事对象的实例;
  3.IColleague同时接口:此接口供调停者使用以实现协调;
  4.XColleagueImpl(具体同事类):维护调停者对象并在需要时调用调停者的协作方法。
实现

import java.util.ArrayList;
//抽象调停者
abstract class AbstractMediator {//注册同事public abstract void register(AbstractColleague ac);//协调各同事对象实现协作行为public abstract void ColleagueChanged(AbstractColleague ac);
}
//抽象同事
abstract class AbstractColleague {private AbstractMediator med; //每个同事都知道中介者,故要引入中介者public AbstractColleague(AbstractMediator mediator) { //通过构造函数传入this.med = mediator;}public abstract void action(); //对象的操作行为public void changed() { //把交互行为发送给中介者med.ColleagueChanged(this);}
}
//具体调停者
class ConcreteMediator extends AbstractMediator {//中介者要维护一个同事列表private ArrayList<AbstractColleague> colleagueList = new ArrayList<>();@Overridepublic void register(AbstractColleague ac) {colleagueList.add(ac);}@Overridepublic void ColleagueChanged(AbstractColleague ac) {for (int i = 0; i < colleagueList.size(); i++) {if (colleagueList.get(i) == ac) {colleagueList.get(i).action();}}}
}//具体同事
class ConcreteColleagueA extends AbstractColleague {public ConcreteColleagueA(AbstractMediator mediator) { //同事要知道中介者super(mediator);mediator.register(this); //把自己注册给中介者}@Overridepublic void action() { //对象的操作行为,由中介者来调用System.out.println("AAAAAAAAAAAAAAA");}
}class ConcreteColleagueC extends AbstractColleague {public ConcreteColleagueC(AbstractMediator mediator) {super(mediator);mediator.register(this);}@Overridepublic void action() {System.out.println("CCCCCCCCCCCCCCC");}
}class ConcreteColleagueB extends AbstractColleague {public ConcreteColleagueB(AbstractMediator mediator) {super(mediator);mediator.register(this);}@Overridepublic void action() {System.out.println("BBBBBBBBBBBBBBB");}
}class MediatorTest {public static void main(String[] args) {AbstractMediator mediator = new ConcreteMediator();AbstractColleague colleagueA = new ConcreteColleagueA(mediator);AbstractColleague colleagueB = new ConcreteColleagueB(mediator);AbstractColleague colleagueC = new ConcreteColleagueC(mediator);colleagueA.changed();colleagueB.changed();colleagueC.changed();}
}

5.模板方法模式

模板方法模式的设计意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类中去实现,这是通过集成的手段来达到对对象的复用。
通过继承的方式实现步骤的重用,子类只需要重写特定的方法即可实现一个特定的流程。
  1、AbstractClass(抽象类):定义一到多个抽象方法(也可以不是抽象方法,但至少应该是virtual方法。视你的应用需要,如果你的AbstractClass负责实现一个通用版本的算法,各子类对该方法进行进一步细化,则只需定义成virtual方法即可),具体的子类将重定义它们以实现一个算法;而且还实现一个模板方法,来定义一个算法的骨架。该模板方法不仅调用前面的抽象方法,也可以调用其他的操作。各抽象方法往往被定义成protected(保护)成员,以保证它们只被模板方法调用,而TemplateMethod往往被定义成public非虚成员函数。
  2、ConcreteClass(具体类):实现父类中的抽象方法以完成算法中与特定子类相关的步骤
实现

abstract class QueryTemplate {  //抽象类:算法的模板//Template Method:模板方法,一般为public的,用来执行算法的各步public void doQuery() {formatConnect();formatSelect();}//算法的骨架,一般为protected的,由子类来实现它们//可见,子类并不能改变算法的框架结构,但可以改变算法的实现步骤protected abstract void formatConnect();protected abstract void formatSelect();
}class OracleQT extends QueryTemplate { //实现算法的具体子类@Overridepublic void formatConnect() {System.out.println("格式化Qracle数据库连接");}@Overridepublic void formatSelect() {System.out.println("格式化Oracle数据库查询");}
}class MysqlQT extends QueryTemplate {@Overridepublic void formatConnect() {System.out.println("格式化Mysql数据库连接");}@Overridepublic void formatSelect() {System.out.println("格式化Mysql数据库查询");}
}public class TemplateTestClient {public static void main(String[] args) {QueryTemplate oracleQT = new OracleQT();oracleQT.doQuery(); //调用抽象模板的模板方法,以执行算法QueryTemplate mysqlQT = new MysqlQT();mysqlQT.doQuery();}
}

解释器模式
解释器模式给定一种语言,定义它的文法标识,并定义一个解释器,然后这个解释器将使用该文法标识来解释语言中的句子。
Expression表达式接口:声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
终结符表达式:实现与文法中的终结符相关联的解释操作,一个句子中的每个终结符都需要使用该类的一个实例。
非终结符表达式,对位文法中的每一条规则都需要一个非终结表达式类,来为文法中的非终结符实现解释操作,解释操作一般要递归地调用表示之前那些对象的解释操作。
运算器:表示该文法定义的语言中一个特定的句子的抽象语法树。
客户端:驶入需要解释的表达式,调用运算器进行解释动作。
实现

import java.util.HashMap;
import java.util.Map;class Context {  //上下文环境private Map valueMap = new HashMap();//一个变量对应一个值,相当于文法的一个推导规则public void addValue(Variable x, int y) {Integer yi = new Integer(y);valueMap.put(x, yi);}//从左边的变量(即非终结符),返回右边的终结符public int LookupValue(Variable x) {int i = ((Integer) valueMap.get(x)).intValue();return i;}
}//AbstractExpression:抽象表达式,也可以用接口来实现
abstract class Expression {public abstract int interpret(Context con); //声明一个抽象的解释操作
}//TerminalExpression:终结符表达式
//实现与文法中的终结符相关联的解释操作。句子中的每个
//终结符需要该类的一个实例与之对应
class Constant extends Expression {private int i;public Constant(int i) {this.i = i;}@Overridepublic int interpret(Context con) { //用文法解释终结符:直接返回此终结符return i;}
}//单个非终结符(变量)的表达式,文法每条规则左边的非终结符需要该类的一个实例
class Variable extends Expression {@Overridepublic int interpret(Context con) {//this为调用interpret方法的Variable对象return con.LookupValue(this);}
}//NonterminalExpression:非终结符表达式R1+R2,有多个非终结符
class Add extends Expression {private Expression left, right;public Add(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context con) { //用文法来解释非终结符表达R1+R2//一般要递归地调用表示从R1到Rn的那些对象的解释操作        return left.interpret(con) + right.interpret(con);}
}class Subtract extends Expression {private Expression left, right;public Subtract(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context con) {return left.interpret(con) - right.interpret(con);}
}class Multiply extends Expression {private Expression left, right;public Multiply(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context con) {return left.interpret(con) * right.interpret(con);}
}class Division extends Expression {private Expression left, right;public Division(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context con) {try {return left.interpret(con) / right.interpret(con);} catch (ArithmeticException ae) {System.out.println("被除数为0!");return -11111;}}
}//测试程序,计算 (a*b)/(a-b+2)
public class InterpreterTest {private static Expression ex;private static Context con;public static void main(String[] args) {con = new Context();//设置变量、常量Variable a = new Variable();Variable b = new Variable();Constant c = new Constant(2);//为变量赋值con.addValue(a, 8);con.addValue(b, 7); //这些工作相当于完成文法的存储//运算,对句子的结构(即抽象语法树)由我们自己来分析和构造//可见解释器模式并没有说明如何创建一个抽象语法树        ex = new Division(new Multiply(a, b), new Add(new Subtract(a, b), c));System.out.println("运算结果为:" + ex.interpret(con));}
}

java设计模式-行为型模式相关推荐

  1. JAVA设计模式 - 创建型模式总结

    JAVA设计模式 - 单例模式 JAVA设计模式 - 工厂方法模式 JAVA设计模式 - 抽象工厂模式 JAVA设计模式 - 原型模式 JAVA设计模式 - 建造者模式 1 . 创建型模式的定义 顾名 ...

  2. java设计模式5--原型模式(Prototype)

    本文地址:http://www.cnblogs.com/archimedes/p/java-prototype-pattern.html,转载请注明源地址. 原型模式 用原型实例指定创建对象的种类,并 ...

  3. 从零开始学习Java设计模式 | 创建型模式篇:原型模式

    在本讲,我们来学习一下创建型模式里面的第四个设计模式,即原型模式. 概述 原型模式就是指用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象. 这段话读起来有点绕,是不是? ...

  4. 【Java设计模式 - 创建型模式1】单例模式

    java设计模式之单例模式 简介 场景 实现 单例模式的几种实现方式 懒汉式,线程不安全 懒汉式,线程安全 饿汉式 双检锁/双重校验锁(DCL,即 double-checked locking) 登记 ...

  5. 从零开始学习Java设计模式 | 创建型模式篇:建造者模式

    在本讲,我们来学习一下创建型模式里面的最后一个设计模式,即建造者模式. 概述 建造者模式是指将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示. 读完这句话之后,我估计很多人都已经懵 ...

  6. 从零开始学习Java设计模式 | 创建型模式篇:抽象工厂模式

    在本讲,我们来学习一下创建型模式里面的第三个设计模式,即抽象工厂模式. 前言 前面介绍的工厂方法模式中考虑的是一类产品,如畜牧场只养动物.电视机厂只生产电视机(不生产空调.冰箱等其它的电器).计算机学 ...

  7. Java设计模式——行为型模式:模板方法模式

    例如,去银行办理业务一般要经过以下4个流程:取号.排队.办理具体业务.对银行工作人员进行评分等,其中取号.排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人 ...

  8. Java设计模式——行为型模式之观察者模式

    一.前言 在生活中我们会遇到这样的场景:用水壶烧开水.当水烧开时,你会有一个关火的过程.在烧水的过程中,你一直观察着这个烧水的进度,当它的状态改变时会触发你关火的这个动作.观察者模式就是处理这种场景而 ...

  9. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

最新文章

  1. 【Ubuntu】apt-get命令小结
  2. flutter中的生命周期
  3. 软件开发生命周期中的设计阶段_BIM咨询在设计阶段包含哪些内容?体现了哪些价值?...
  4. docker 的mysql镜像使用手册 官网原文 日期2017-05-25
  5. matlab最小错误率决策,利用MATLAB实现最小错误率贝叶斯判别
  6. Jquery事件、冒泡、委托与节点
  7. 日语学习-多邻国-关卡1-家居
  8. Android中从源码分析关于AsyncTask的使用
  9. c语言全段字符的类别,中兴LTE试题-1
  10. 广义pareto分布_帕累托分布广义帕累托分布
  11. 俱乐部2006年的首次活动-ASP.NET Webpart 开发交流会暨2005回顾
  12. 从菜鸟到架构师(三)
  13. vue+mars3d 组件封装与应用 +简单示例
  14. App内嵌H5活动页面携带用户token
  15. CTO、技术总监和技术经理有啥区别?
  16. 前端网络基础 - 跨域xhr/fetch
  17. 《你可以不平凡》-- 周杰伦在北京大学百年讲堂的演讲
  18. jquery中的ajax方法请求后台数据
  19. FPGA数字时钟系统-设计教程
  20. 论金融IT公司程序员的职业发展

热门文章

  1. FlashFXP.v3.6.0.1240.Final-YAG
  2. JS(第二十四课)JS高级Es6语法
  3. 场景测试法的基本步骤
  4. Sliverlight实例之 使用 ControlTemplate 自定义按钮的外观
  5. 无垠的太空第三季在线观看_百度云迅雷下载
  6. 盘阿里云ECS内挖矿程序
  7. 蜜罐技术怎样区分正常用户和黑客
  8. 推荐定位信息(GPRMC)
  9. 小木屋图书如何依靠用户增长,达到融资千万?
  10. Android多效果轮播器/Banner实现,支持无限轮播、自动切换、指示器动画