何为观察者模式?这里先引出一个大家熟悉的程序。
package com.piniheaven;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Obersevr {
public static void main(String[] args) {
init();
}
public static void init()
{
JFrame jf=new JFrame("Oberser");
JButton jb=new JButton("Click Me");
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Angel says:Don't do it!");
}
});
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Demon says: Do it!");
}
});
jf.add(jb,BorderLayout.CENTER);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setBounds(50,50,300,200);
jf.setVisible(true);
}
}
运行界面:
点击按钮输出结果:
Demon says: Do it!
Angel says:Don't do it!
这里模拟的是一个小型天气预报系统。
代码如下:
Subject.h
#ifndef Subject_H
#define Subject_H
#include"Observer.h"
class Subject
{
public:
virtual void regist(Observer &observer)=0;
virtual void remove(Observer &observer)=0;
virtual void notify()=0;
};
#endif
Display.h
#ifndef Display_H
#define Display_H
class Display
{
public:
virtual void show()=0;
};
#endif
Oberserver.h
#ifndef Observer_H
#define Observer_H
class Observer
{
public:
Observer(int ID):id(ID){}
Observer(){}
virtual void update(float degree,float humidity)=0;
bool operator!=(Observer &ob)
{
return ob.id==this->id;
}
private:
int id;
};
#endif
WeatherStation.h
#ifndef WeatherStation_H
#define WeatherStation_H
#include"Subject.h"
#include"Link.h"
#include"Observer.h"
class WeatherStation:public Subject
{
private:
Link<Observer&> observerList;
float degree;
float humidity;
public:
WeatherStation():degree(25.0),humidity(25.0){}
void dataChange(float degree,float humidity);
void regist(Observer &observer)
{
observerList.addNode(observer);
}
void remove(Observer &observer)
{
observerList.deleteNode(observer);
}
void notify()
{
for(int i=0;i<observerList.size();i++)
{
observerList[i].update(degree,humidity);
}
}
};
void WeatherStation::dataChange(float degree,float humidity)
{
this->degree=degree;
this->humidity=humidity;
notify();//When the data changes,notify all observers
}
#endif
CurrentDisplay.h
#ifndef CurrentDisplay_H
#define CurrentDisplay_H
#include "Observer.h"
#include"Display.h"
#include<iostream>
using std::cout;
using std::endl;
class CurrentDispaly:public Observer,public Display
{
private:
float degree;
float humidity;
int id;
public:
CurrentDispaly():id(1),degree(25.0),humidity(25.0){}
CurrentDispaly(int ID):id(ID),degree(25.0),humidity(25.0){}
void update(float degree,float humidity)
{
this->degree=degree;
this->humidity=humidity;
show();
}
void show()
{
cout<<"present degree is : "<<degree<<endl;
cout<<"present humidity is: "<<humidity<<endl<<endl;
}
};
#endif
WeatherPredict.h
#ifndef WeatherPredict_H
#define WeatherPredict_H
#include "Observer.h"
#include"Display.h"
#include<iostream>
using std::cout;
using std::endl;
class WeatherPredict:public Observer,public Display
{
private:
float degree;
float humidity;
float currentDegree;
float currentHumidity;
int id;
public:
WeatherPredict():id(0),degree(25.0),humidity(25.0),currentDegree(25.0),currentHumidity(25.0){}
WeatherPredict(int ID):Observer(id),degree(25.0),humidity(25.0),currentDegree(25.0),currentHumidity(25.0){}
void update(float degree,float humidity)
{
this->degree=degree;
this->humidity=humidity;
show();
this->currentDegree=degree;
this->currentHumidity=humidity;
}
void show()
{
if(degree>currentDegree)
{
cout<<"Look out! The weather is arised."<<endl;
}
else if(degree<currentDegree)
{
cout<<"Look out!The weather turning to cool,please put on more clothes,if necessary!"<<endl;
}
else
{
cout<<"The degree is all the same!"<<endl;
}
if(humidity>currentDegree)
{
cout<<"Look out! The humidity is arised.Maybe,it is going to rain."<<endl;
}
else if(humidity<currentDegree)
{
cout<<"Look out!The humidity is fall down,please drink more water!"<<endl;
}
else
{
cout<<"The humidity is all the same!"<<endl;
}
}
Node.h
#ifndef Node_H
#define Node_H
#include"WeathePredict.h"
WeatherPredict wp;
template<class T> class Link;
template<class T>
class Node
{
friend Link<T>;
public:
Node(T d):data(d){}
Node():data(wp){}
private:
T data;
Node<T> *next;
};
#endif
Link.h
#ifndef Link_H
#define Link_H
#include"Node.h"
template<class T>
class Link
{
private:
Node<T> *head;
int length;
public:
Link();
Link<T> &addNode(T data);
Link<T> &deleteNode(T data);
int size();
T operator[](int n)
{
Node<T> *temp=head->next;
for(int t=0;t<n;t++)
{
temp=temp->next;
}
return temp->data ;
}
~Link();
};
template<class T>
Link<T>::Link()
{
length=0;
head=new Node<T>;
head->next=NULL;
}
template<class T>
Link<T>& Link<T>:: addNode(T data)
{
Node<T> *temp=new Node<T>(data);
temp->next=NULL;
Node<T> *p=head;
while(p->next)
{
p=p->next;
}
p->next=temp;
length++;
return *this;
}
template<class T>
Link<T>& Link<T>:: deleteNode(T data)
{
Node<T> *p=head;
while(p->next &&p->next->data!=data)
{
p=p->next;
}
if(p->next )
{
Node<T> *temp=p->next ;
p->next=p->next->next;
delete temp;
length--;
}
return *this;
}
template<class T>
int Link<T>::size()
{
return length;
}
template<class T>
Link<T>::~Link()
{
while(head)
{
Node<T> *temp=head;
head=head->next ;
delete temp;
}
length=0;
}
#endif
main.cpp
#include<iostream>
#include"WeatherStation.h"
#include"WeathePredict.h"
#include"CurrenDisplay.h"
using namespace std;
int main(void)
{
CurrentDispaly curren_display;
WeatherPredict weather_predict;
WeatherStation weather_staton;
weather_staton.regist(curren_display);
weather_staton.regist(weather_predict);
weather_staton.dataChange(28.2,21.3);
weather_staton.dataChange(18.2,31.3);
weather_staton.dataChange(28.2,41.3);
weather_staton.dataChange(28.2,21.3);
weather_staton.dataChange(28.2,21.3);
weather_staton.dataChange(28.2,21.3);
return 0;
}