一、状态模式

【状态接口】

/***
* 房间"状态"接口
*/
package cn.sxt.state; public interface State {
void handle(); }

【管理状态类】

/***
* 环境、上下文类, 管理房间的状态
*如果这是银行系统,这个类就是账号,根据状态的不同,进行不同的操作
*/
package cn.sxt.state; public class HomeContext {
private State state; public void setState(State state) {
System.out.println("修改房间的状态!");
this.state = state;
state.handle();
} }

【房间状态】

/***
* "空闲"状态
*/
package cn.sxt.state; public class FreeState implements State{ @Override
public void handle() {
System.out.println("房间空闲,没人入住!"); }
} /***
* "有人住、房间有人"类
*/
package cn.sxt.state; public class CheckedInState implements State{
@Override
public void handle() {
System.out.println("房间有人,请勿打扰!"); }
} /***
* "已预订" 类
*/
package cn.sxt.state; public class BookedState implements State{
@Override
public void handle() {
System.out.println("房间有人预定!"); } }

【客户类】

/**
* 客户
*/
package cn.sxt.state; public class Client {
public static void main(String[] args) {
HomeContext ctx=new HomeContext();//状态对象
ctx.setState(new FreeState());//设置状态为 空闲状态
ctx.setState(new BookedState());
} }

二、观察者模式(Observer)

【目标类-广播站】

/**
* "目标"类 广播站
*/
package cn.sxt.observer; import java.util.ArrayList;
import java.util.List; public class Subject {
protected List<Observer> list=new ArrayList<Observer>(); public void registerObserver(Observer obs){
list.add(obs);//注册观察者,就是听众
} public void removeObserver(Observer obs){
list.remove(obs);//删除观察者,就是听众
} public void notifyAllObserver() {//通知所有观察者,更新状态
for (Observer obs : list) {
obs.update(this);
}
} } /***
* "一个具体的广播站"
*/
package cn.sxt.observer; public class ConcreteSubject extends Subject {
private String state; public String getState() {
return state;
} public void setState(String state) {
this.state = state;
this.notifyAllObserver();//状态变化有变化请通知其它的观察者
} }

【观察者-听众】

/***
* "观察者"接口
*/
package cn.sxt.observer; public interface Observer {
void update(Subject subject); } /***
* A观察者
*/
package cn.sxt.observer; public class ObserverA implements Observer{
private String myState;//自己的状态跟目标对象保持一致 @Override
public void update(Subject subject) {
myState=( (ConcreteSubject)subject ).getState();
} public String getMyState() {
System.out.print("系统消息:");
return myState;
} public void setMyState(String myState) {
this.myState = myState;
} }

【客户端】

/**
*
*/
package cn.sxt.observer; public class Client {
public static void main(String[] args) {
//目标对象,广播站
ConcreteSubject subject=new ConcreteSubject();
//3个观察者 听众
ObserverA obs1=new ObserverA();
ObserverA obs2=new ObserverA();
ObserverA obs3=new ObserverA(); //让这3个观察者添加到观察者容器中
subject.registerObserver(obs1);
subject.registerObserver(obs2);
subject.registerObserver(obs3); //改变状态 开始广播
subject.setState("明天上午8:00开会"); //看看观察者的状态
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
}
}

使用系统提供的观察类

【具体的广播站】

/***
* 一个具体的广播站 ,使用Java提供的 目标类java.util.Observable
*/
package cn.sxt.observer2; import java.util.Observable; public class ConcreteSubject extends Observable {
private String state; public void setState(String state) {
this.state = state;
setChanged();//调用jar的方法,表示目标对象已经做了更改
notifyObservers(state);//通知所有的观察者,jar包的方法
} public String getState() {
return state;
} }

【具体的听众】

/**
*
*/
package cn.sxt.observer2; import java.util.Observable;
import java.util.Observer; public class ObserverA implements Observer{//使用jar中的接口 private String myState; @Override
public void update(Observable o, Object arg) {//2个参数:主题对象
myState=( (ConcreteSubject) o).getState();
} public String getMyState() {
System.out.print("系统消息:");
return myState;
} public void setMyState(String myState) {
this.myState = myState;
} }

【客户端测试】

/**
*
*/
package cn.sxt.observer2; public class Client {
public static void main(String[] args) {
//目标对象,广播站
ConcreteSubject subject=new ConcreteSubject();
//3个观察者 听众
ObserverA obs1=new ObserverA();
ObserverA obs2=new ObserverA();
ObserverA obs3=new ObserverA(); //添加观察者
subject.addObserver(obs1);
subject.addObserver(obs2);
subject.addObserver(obs3); //改变状态 开始广播
subject.setState("明天上午9:00开会"); //看看观察者的状态
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
}
}

三、备忘录模式(memento)

【源发类】

/***
*源发器类 保存雇员的信息
*/
package cn.sxt.memento; public class Emp {
private String name;
private int age;
private double salary; //进行备忘操作
public EmpMemento memento() {
return new EmpMemento(this);//表示当前对象的信息
}
//进行数据恢复,恢复备忘录的值
public void recovery(EmpMemento mmt) {
this.name=mmt.getName();
this.age=mmt.getAge();
this.salary=mmt.getSalary();
} public Emp(String name, int age, double salary) {
super();
this.name = name;
this.age = age;
this.salary = salary;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public double getSalary() {
return salary;
} public void setSalary(double salary) {
this.salary = salary;
} }

【备忘录类】

/***
* 备忘录类
*/
package cn.sxt.memento; 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();
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public double getSalary() {
return salary;
} public void setSalary(double salary) {
this.salary = salary;
} }

【管理备忘录】

/***
* 负责人类,负责管理备忘录对象
*/
package cn.sxt.memento; import java.util.ArrayList;
import java.util.List; public class CareTaker {
private EmpMemento memento; //private List<EmpMemento>list =new ArrayList<EmpMemento>(); 可以存多个备忘录点,也可以搞搞个栈 public EmpMemento getMemento() {
return memento;
} public void setMemento(EmpMemento memento) {
this.memento = memento;
} }

【测试】

/**
*
*/
package cn.sxt.memento; public class Client {
public static void main(String[] args) {
CareTaker taker=new CareTaker();
Emp emp1=new Emp("Tom", 10, 7000);
System.out.println("原始的信息:"+emp1.getName()+"--"+emp1.getAge()+"--"+emp1.getSalary()); taker.setMemento(emp1.memento());//原始信息做了一次备份 emp1.setAge(18);
emp1.setSalary(9000);//对信息做了一次修改
System.out.println("修改后的信息:"+emp1.getName()+"--"+emp1.getAge()+"--"+emp1.getSalary()); emp1.recovery(taker.getMemento());//恢复信息到taker对象管理的备忘录点
System.out.println("恢复后的信息:"+emp1.getName()+"--"+emp1.getAge()+"--"+emp1.getSalary());
} }

[19/05/02-星期四] GOF23_行为型模式(状态模式、观察者模式、备忘录模式)的更多相关文章

  1. 《Android源码设计模式》--状态模式--责任链模式--解释器模式--命令模式--观察者模式--备忘录模式--迭代器模式

    [状态模式] No1: Wifi设置界面是一个叫做WifiSetting的Fragment实现的 No2: 在不同的状态下对于扫描Wifi这个请求的处理是完全不一样的.在初始状态下扫描请求被直接忽略, ...

  2. 设计模式学习之备忘录模式(Memento,行为型模式)(19)

    假如我们已经记录一个人的个人信息,但是发现信息写错了,然后我先备份下再去修改,结果发现原来的信息是正确的,于是我就看备份的个人信息还原到初始的状态,下面我们用代码去实现 class Program { ...

  3. C#设计模式之二十二备忘录模式(Memeto Pattern)【行为型】

    一.引言   今天我们开始讲"行为型"设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就 ...

  4. 备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)

    备忘录模式 Memento   沿着脚印,走过你来时的路,回到原点.     苦海翻起爱恨   在世间难逃避命运   相亲竟不可接近   或我应该相信是缘份   一首<一生所爱>触动了多少 ...

  5. C#设计模式之二十二备忘录模式(Memento Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就是对某个对象的状态进行保 ...

  6. java设计模式--行为型模式--备忘录模式

    备忘录模式,我们平常所做的备忘录么.还得深深研究哦. 备忘录模式: 备忘录模式 概述 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状 ...

  7. 设计模式20---设计模式之备忘录模式(Memento)(行为型)

    1.讲解备忘录模式 备忘录模式(Memento Pattern)又叫做快照模式(Snapshot Pattern)或Token模式,是GoF的23种设计模式之一,属于行为模式. 1.1定义 在不破坏封 ...

  8. 设计模式(18)--Memento(备忘录模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式. ...

  9. 行为型模式(十) 备忘录模式(Memento)

    一.动机(Motivate) 我们看上图,一个对象肯定会有很多状态,这些状态肯定会相互转变而促进对象的发展,如果要想在某一时刻把当前对象回复到以前某一时刻的状态,这个情况用"备忘录模式&qu ...

  10. C#设计模式-备忘录模式

    访问者模式的实现是把作用于某种数据结构上的操作封装到访问者中,使得操作和数据结构隔离.而本文要介绍的备忘者模式与命令模式有点相似,不同的是,命令模式保存的是发起人的具体命令(命令对应的是行为),而备忘 ...

随机推荐

  1. SQL Server中的流控制语句

    begin···end 该语句定义sql代码块,通常在if和while语句中使用 declare @num int ; ; begin ; print 'hello word' end if···el ...

  2. sql prompt 不能用

    问题描述: 安装成功后,打开sql server 工具栏不显示菜单,并弹出提示错误信息: SQL Prompt has been disabled due to an error with the r ...

  3. SpringJunit4 进行单元测试(实例篇--紧接上一章)

    前言: 在做WEB项目时,我们写好了一个Dao和Service后,接下来就是要进行单元测试,测试的时候还要等到Spring容器全部加载完毕后才能进行,然后通过拿到ApplicationContext对 ...

  4. 阿里云服务器windows server流量不大的情况下,tomcat经常出现访问阻塞,手动ctrl+c或者点击右键又访问正常

    我被这个问题折磨了好几天,因为这两天要帮别人做推广,不能再出现这样的情况了,不然广告费就白烧了,所以特意查了一下资料,结果解决方案被我找出来了. 问题发生原因是因为打开编辑选项后,一不小心点到dos窗 ...

  5. FisherYates费雪耶兹随机置乱算法

    public class FisherYates { public static void main(String[] args) { int[] arr = new int[10]; // 初始有序 ...

  6. C# 调用C++DLL 类型转换

    内容转自网上····这里做 备份··· 原文链接: http://blog.csdn.net/miss_easy/article/details/52470964 /C++中的DLL函数原型为 //e ...

  7. cf1060E. Sergey and Subway(树形dp)

    题意 题目链接 Sol 很套路的题 直接考虑每个边的贡献,最后再把奇数点的贡献算上 #include<bits/stdc++.h> #define Pair pair<int, in ...

  8. 让你跟上nodejs的资源

    For a long time, JavaScript developers hoped for a server-side solution that would allow them to ful ...

  9. Postman如何调试

    在用Postman接口测试过程当中,肯定少不了调试,下面记录一下Postman如何通过控制台输出进行调试: 一.打开控制台(View-Show Postman Console) 二.预置测试数据(测试 ...

  10. CentOS7安装minio

    [root@localhost ~]# wget https://dl.minio.io/server/minio/release/linux-amd64/minio -bash: wget: 未找到 ...