[19/05/02-星期四] GOF23_行為型模式(狀態模式、觀察者模式、備忘錄模式)
阿新 • • 發佈:2019-04-30
car 參數 home arr 進行 hand dsta sta rec
一、狀態模式
【狀態接口】
/*** * 房間"狀態"接口 */ package cn.sxt.state; public interface State { void handle(); }
【管理狀態類】
/*** * 環境、上下文類, 管理房間的狀態 *如果這是銀行系統,這個類就是賬號,根據狀態的不同,進行不同的操作 */ package cn.sxt.state; public class HomeContext { private State state; publicvoid 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 classBookedState 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_行為型模式(狀態模式、觀察者模式、備忘錄模式)