[19/05/02-星期四] GOF23_行为型模式(状态模式、观察者模式、备忘录模式)

一、状态模式

【状态接口】

/***
 * 房间"状态"接口
 */
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());
    }

}

猜你喜欢

转载自www.cnblogs.com/ID-qingxin/p/10793641.html