十六:解释器模式(interpreter)
1.介绍:用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的 编译器和解释器设计。当我们需要开发一种新的语言时,可以考虑使用解释器模式。尽量不要使用解释器模式,后期维护会有很大麻烦。在项目中,可以使用 Jruby,Groovy、java的js引擎来替代解释器的作用,弥补java语言的不足。
2.使用场景:
- EL表达式式的处理
- 正则表达式解释器
- SQL语法的解释器
十七:访问者模式(visitor)
1.定义:表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变个元素 的类的前提下定义作用于这些元素的新操作。对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接 口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访 问者其访问方式也有所不同。
2.开发中的场景(应用范围非常窄,了解即可):
- XML文档解析器设计
- 编译器的设计
- 复杂集合对象的处理
十八:策略模式(stratrgy)
1.介绍:策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族 中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新 的算法。并且由客户端决定调用哪个算法。
2.案例:不同客户不同折扣
//策略接口,算法接口,实现算法族
public interface Stratrgy {
//不同客户打不同的折扣
double getPrice(double price);
}
//新客户小批量
class NewCustomerFewStratrgy implements Stratrgy{
@Override
public double getPrice(double price) {
return price;//原价
}
}
//新客户大批量
class NewCustomerMarryStratrgy implements Stratrgy{
@Override
public double getPrice(double price) {
return price*0.9;//9折
}
}
//老客户小批量
class OldCustomerFewStratrgy implements Stratrgy{
@Override
public double getPrice(double price) {
return price*0.85;//85折
}
}
//老客户大批量
class OldCustomerMarryStratrgy implements Stratrgy{
@Override
public double getPrice(double price) {
return price*0.8;//8折
}
}
//负责具体策略类交互
public class Context {
//策略类
private Stratrgy stratrgy;
public Context(Stratrgy stratrgy) {
super();
this.stratrgy = stratrgy;
}
//根据不同的策略返回不同的值
private void printPrice(double price){
System.out.println(stratrgy.getPrice(price));
}
public static void main(String[] args) {
Stratrgy newCustomerFewStratrgy = new NewCustomerFewStratrgy();
Context context = new Context(newCustomerFewStratrgy);
context.printPrice(89);
}
}
3.本质:分离算法,选择实现。
4.常用场景:
- JAVASE中GUI编程中,布局管理
- Spring框架中,Resource接口,资源访问策略
- javax.servlet.http.HttpServlet#service()
十九:模板方法模式(template method)
1.介绍:定义一个操作中的算法骨架,将某些步骤延迟到之类中实现,这样新的子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定步骤。
2.核心:具体步骤父类中已经定义,具体实现在子类中。
3.案例:
//银行办理业务模板
public abstract class BankTemplateMethod {
//具体方法
public void takeNumber(){
System.out.println("取号排队");
}
public abstract void transact(); //办理具体的业务 //钩子方法,子类实现
public void evaluate(){
System.out.println("反馈评分");
}
public final void process(){
this.takeNumber();
this.transact();
this.evaluate();
}
public static void main(String[] args) {
BankTemplateMethod bankTemplateMethod = new BankTemplateMethod() {
@Override
public void transact() {
System.out.println("取钱啦........");
}
};
bankTemplateMethod.process();
}
}
4.钩子方法/回调方法:父类在方法中回调子类实现的方法。
5.啥时候用模板方法模式:实现一个算法步骤很固定,但是某些部分易变,易变部分可以给子类实现。常见的Spring中的XXXTemplat就是模板方法模式的实现
二十:状态模式(state)
1.应用:不同的状态对应不同的行为适用于状态模式,比如红绿灯的运行。
2.案例:模拟酒店客房状态(入住,空闲,已预定)
//状态抽象接口
public interface State {
void handler();
}
//空闲状态
class FreeState implements State{
@Override
public void handler() {
System.out.println("房间空闲......");
}
}
//预定状态
class BookedState implements State{
@Override
public void handler() {
System.out.println("房间已预订......");
}
}
//入住状态
class CheckedState implements State{
@Override
public void handler() {
System.out.println("房间已入住......");
}
}
//房间类
public class HomeContext {
private State state;
public void setState(State state) {
System.out.println("修改状态.......");
this.state = state;
this.state.handler();
}
public static void main(String[] args) {
HomeContext context = new HomeContext();
//切换不同状态,对应不同行为
context.setState(new FreeState());
context.setState(new BookedState());
context.setState(new CheckedState());
}
}
3.核心:用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题
二十一:观察者模式(observer)
1.核心:观察者模式主要用于1:N的通知,当一个对象(目标对象)状态改变时,需要告知一系列对象(观察者对象)作出响应。通知观察者对象的方式:
- 推:每次都会把通知已广播的形式推送给观察者,所有观察者只能被动接收
- 拉:观察者只要知道目标对象变化就可以,至于啥时候获取,啥时候处理,有观察者自己决定。
2.案例:
//观察者接口
public interface Observer {
void update(int state);
}
//观察者A
class ObserverA implements Observer{
private int state;
@Override
public void update(int state) {//同步状态
this.state=state;
System.out.println("ObserverA做出反应,改变状态为"+this.state+".......");
}
}
//观察者B
class ObserverB implements Observer{
private int state;
@Override
public void update(int state) {//同步状态
this.state=state;
System.out.println("ObserverB做出反应,改变状态为"+this.state+".......");
}
}
//目标对象
public class Subject {
private List<Observer> observers=new ArrayList<Observer>();
public void register(Observer observer){
observers.add(observer);
}
public void remove(Observer observer){
observers.remove(observer);
}
//通知所有观察者更新状态
public void notifyAllObserver(int state){
for (Observer observer : observers) {
observer.update(state);
}
}
}
//具体目标对象
class ConcreteSubject extends Subject{
private int state;
public void setState(int state) {
this.state = state;
this.notifyAllObserver(this.state);
}
}
public class Client {
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();
concreteSubject.register(new ObserverA());
concreteSubject.register(new ObserverB());
concreteSubject.setState(1);
concreteSubject.setState(2);
concreteSubject.setState(3);
}
}
3.JDK提供的API
//目标对象,继承JDK的Observable
public class ConcreteSubject2 extends Observable{
private int state;
public void setState(int state) {
this.state = state;
//目标对象已经被更改,Observable中方法
setChanged();
//通知所有观察者,Observable中方法
notifyObservers(this.state);
}
}
//观察者
public class Observer2 implements Observer {
private int state;
@Override
public void update(Observable o, Object object) {
this.state=(int)object;
System.out.println("改变状态为"+state+".........");
}
public static void main(String[] args) {
//创建目标对象
ConcreteSubject2 concreteSubject2 = new ConcreteSubject2();
//添加观察者
concreteSubject2.addObserver(new Observer2());
concreteSubject2.addObserver(new Observer2());
//改变目标对象状态
concreteSubject2.setState(2);
}
}
4.应用场景:
- 聊天室程序的,服务器转发给所有客户端
- Servlet中,监听器的实现
- 商城中,群发某商品打折信息
二十二:备忘录模式(memento)
1.核心:就是保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态。
2.案例:
//原发器类,需要备忘的对象
public class Emp {
private String name;
private int age;
private double salary;
//进行备忘操作,返回备忘对象
public EmpMemento empMemento(){
return new EmpMemento(this);
}
//进行数据恢复,恢复为指定对象的值
public void recovery(EmpMemento empMemento){
this.name=empMemento.getName();
this.age=empMemento.getAge();
this.salary=empMemento.getSalary();
}
//全参构造,get,set,toString
}
//备忘录对象
public class EmpMemento {
private String name;
private int age;
private double salary;
public EmpMemento(Emp emp) {
this.name=emp.getName();
this.age=emp.getAge();
this.salary=emp.getSalary();
}
//全参构造,get,set
}
//负责人类,负责管理备忘录对象
public class CareTaker {
//保存多次,通过容器
private EmpMemento empMemento;
public EmpMemento getEmpMemento() {
return empMemento;
}
public void setEmpMemento(EmpMemento empMemento) {
this.empMemento = empMemento;
}
public static void main(String[] args) {
CareTaker careTaker = new CareTaker();
Emp emp = new Emp("张三", 18, 900);
System.out.println("第一次创建对象......."+emp.toString());
//备份一次
careTaker.setEmpMemento(emp.empMemento());
//修改
emp.setName("李四");
emp.setAge(25);
emp.setSalary(1200);
System.out.println("第二次修改对象......."+emp.toString());
//恢复对象
emp.recovery(careTaker.getEmpMemento());
//恢复为第一次创建的对象
System.out.println("恢复为第一次创建对象......"+emp.toString());
}
}
3.应用场景:
- 数据库软件中的,事务管理中的,回滚操作
- 普通软件中的,撤销操作
- Photoshop软件中的,历史记录