观察者模式总结
- 主题:
主题
维护一个观察者列表
,当主题需要通知列表中的所有观察者时,就调用notifyObservers()
方法,具体是调用观察者的update()方法。- 观察者:观察者需要把自己注册进主题中,每个观察者的具体实现写在
update()
方法中。- 在这个过程中必须要理解
多态
概念,既然每个观察者实现了update()
方法,那么主题就可调用每个观察者的update()方法而不关具体实现,“我知道你有update()方法,那么你就去做你的update()方法,而我不关心你怎么做的。”
观察者模式定义
类图
设计原则
Java内置的观察者模式
总结
练习题
1.电子商务系统
代码
文件目录
主题接口
package test3;
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
主题(Customer)
package test3;
import java.util.ArrayList;
public class Customer implements Subject {
private ArrayList observers; // 主题维护一个观察者列表
public Customer() {
observers = new ArrayList();
}
@Override
public void registerObserver(Observer o) {
// TODO Auto-generated method stub
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
// TODO Auto-generated method stub
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObservers() { // notify()里面调用观察者列表里的notify方法
// TODO Auto-generated method stub
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer) observers.get(i);
observer.update();
}
}
public void addCustomer() {
notifyObservers();
//System.out.println(observers.size());
}
}
观察者接口
package test3;
public interface Observer {
public void update();
}
观察者(WelcomLetter)
package test3;
public class WelcomLetter implements Observer {
private Subject subject;
public WelcomLetter(Subject subject) // 把自己注册到哪个主题中去
{
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("发送邮件");
}
}
观察者(AddrVerification)
package test3;
public class AddrVerification implements Observer {
private Subject subject;
public AddrVerification(Subject subject) // 构造函数,把自己注册到主题中去
{
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("查证地址");
}
}
测试程序
package test3;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Customer customer = new Customer(); // 主题
WelcomLetter welcomLetter = new WelcomLetter(customer); // 需要注册
AddrVerification addrVerification = new AddrVerification(customer);
customer.addCustomer();
}
}
2.股票软件
代码
文件目录
主题
package test4;
import java.util.ArrayList;
public class Stock {
private ArrayList<Investor> investors; // 观察者列表
private String stockName;
private double price;
public Stock(String stockName,double price) // 构造函数
{
this.stockName = stockName;
this.price = price;
investors = new ArrayList<Investor>();
}
public void attach(Investor investor) // 观察者列表中加入一个观察者
{
investors.add(investor);
}
public void detach(Investor investor) // 观察者列表中删除一个观察者
{
investors.remove(investor);
}
public String getStockName() {
return stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
double range = Math.abs(price-this.price) / this.price;
this.price = price;
if(range > 0.05)
{
this.notifyInvestor();
}
}
public void notifyInvestor()
{
for(Investor c : investors)
{
c.response(this);
}
}
}
观察者接口
package test4;
// 抽象股民:抽象观察者
public interface Investor {
public void response(Stock stock);
}
观察者
package test4;
/*
* 股民:具体观察者
*/
public class ConcreteInvestor implements Investor {
private String name;
public ConcreteInvestor(String name) {
this.name = name;
}
@Override
public void response(Stock stock) {
// TODO Auto-generated method stub
System.out.println(stock.getStockName() + " 交易所-----" +name + " : 提示风险");
}
}
测试程序
package test4;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Investor investor1,investor2;
investor1 = new ConcreteInvestor("杨过");
investor2 = new ConcreteInvestor("小龙女");
Stock haier = new Stock("青岛海尔",20.00);
haier.attach(investor1); // 注册
haier.attach(investor2); // 注册
haier.setPrice(25.00);
}
}