码迷,mamicode.com
首页 > 其他好文 > 详细

观察者模式

时间:2015-03-30 11:04:59      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:

  GOF:定义了对象之间的“一对多”的依赖关系,这样,当一个对象的状态发生变化时,所有依赖于这个对象的相关对象都被通知并自动更新。

  关键:一对多的依赖关系是这个模式的关键,能使多个Observer(观察者)观察到Subject(主题,即被观察者)的变化。这样解决了相互协作的类中间双耦合的问题,Subject不需要知道有哪些Observer存在,而Observer之间也不需要知道对方的存在。

 

  代码(摘自《漫谈设计模式》):

技术分享
package 设计模式;
import static java.lang.Math.abs;

import java.util.ArrayList;
import java.util.List;

/* 定义了对象之间“一对多”的关系,当一个对象发生变化,其他依赖该对象的相关
 * 对象都会被通知并自动更新
 * Java也提供了观察者模式:java.util.Observable Observer */
public class 观察者模式 {
    public static void main(String[] args) {
        Stock stock = new Stock(19f);
        InstitutionalInvester institutionalInvester = new InstitutionalInvester("Company A", 20f, 18.5f, stock);
        PrivateInvestor privateInvestor = new PrivateInvestor("John", 20f, 18.9f, stock);
        
        stock.setPrice(19.0224f);
        System.out.println();
        
        stock.setPrice(20.923f);
        System.out.println();
        
        stock.setPrice(18.823f);
        System.out.println();
        
        stock.setPrice(19.923f);
    }
    
}

interface StockBuyer {
    void update(float price);
}

class Stock {
    private float price = 0.0f;
    private float maxGainAndLoss = 0.0f;
    List<StockBuyer> buyers;
    
    public Stock(float price) {
        this.price = price;
        buyers = new ArrayList<StockBuyer>();
    }
    
    public void addBuyer(StockBuyer stockBuyer) {
        buyers.add(stockBuyer);
    }
    
    public void notifyBuyer() {
        for (StockBuyer buyer : buyers)
            buyer.update(price);
    }
    
    public void setPrice(float newPrice) {
        if(newPrice < 0) {
            throw new IllegalArgumentException("Price can not be negative");
        }
        
        float oldPrice = price;
        price = newPrice;
        float gainAndLoss = (newPrice-oldPrice) / oldPrice;
        System.out.printf("Previous price: %g. Current price: %g. Loss/Gain: %g%%. \n", 
                oldPrice, newPrice, gainAndLoss*100);
        
        if(abs(gainAndLoss) > maxGainAndLoss) {
            notifyBuyer();
        }
    }
}

class InstitutionalInvester implements StockBuyer {
    private String name;
    private float maxPrice;
    private float minPrice;
    
    public InstitutionalInvester(String name, float maxPrice, float minPrice, Stock stock) {
        this.name = name;
        this.maxPrice = maxPrice;
        this.minPrice = minPrice;
        stock.addBuyer(this);
    }
    
    @Override
    public void update(float price) {
        if(price > maxPrice) {
            System.out.printf("%s is selling 100000 stocks...\n", name);
        }
        if(price < minPrice) {
            System.out.printf("%s is buying 20000 shares....\n", name);
        }
    }
}

class PrivateInvestor implements StockBuyer {
    private String name;
    private float maxPrice;
    private float minPrice;
    
    public PrivateInvestor(String name, float maxPrice, float minPrice, Stock stock) {
        this.name = name;
        this.maxPrice = maxPrice;
        this.minPrice = minPrice;
        stock.addBuyer(this);
    }
    
    @Override
    public void update(float price) {
        if(price > maxPrice) {
            System.out.printf("%s is buying 500 stocks...\n", name);
        }
        if(price < minPrice) {
            System.out.printf("%s is selling 1000 shares....\n", name);
        }
    }
}
View Code

  其实有两种信息推送的方法,(1)Push方式:Subject发送信息给所有Observer;(2)Pull方式:Observer主动获取Subject的信息。

  Java标准库中有java.util.Observable类和java.util.Observer接口来实现观察者模式:

java.util.Observable方法:

 

 

技术分享

  PS.一定要先setChanged才能notifyObservers

java.util.Observer只有一个方法:

技术分享

  利用上述两个工具实现代码如下:

技术分享
package 设计模式;
import static java.lang.Math.abs;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

/* 定义了对象之间“一对多”的关系,当一个对象发生变化,其他依赖该对象的相关
 * 对象都会被通知并自动更新
 * Java也提供了观察者模式:java.util.Observable Observer */
public class 观察者模式 {
    public static void main(String[] args) {
        Stock stock = new Stock(19f);
        InstitutionalInvester institutionalInvester = new InstitutionalInvester("Company A", 20f, 18.5f, stock);
        PrivateInvestor privateInvestor = new PrivateInvestor("John", 20f, 18.9f, stock);
        
        stock.setPrice(19.0224f);
        System.out.println();
        
        stock.setPrice(20.923f);
        System.out.println();
        
        stock.setPrice(18.823f);
        System.out.println();
        
        stock.setPrice(19.923f);
    }
    
}

class Stock extends Observable{
    private float price = 0.0f;
    private float maxGainAndLoss = 0.0f;
    
    public Stock(float price) {
        super();
        this.price = price;
    }
    
    public void setPrice(float newPrice) {
        if(newPrice < 0) {
            throw new IllegalArgumentException("Price can not be negative");
        }
        
        float oldPrice = price;
        price = newPrice;
        float gainAndLoss = (newPrice-oldPrice) / oldPrice;
        System.out.printf("Previous price: %g. Current price: %g. Loss/Gain: %g%%. \n", 
                oldPrice, newPrice, gainAndLoss*100);
        
        if(abs(gainAndLoss) > maxGainAndLoss) {
            setChanged();
            notifyObservers(price);
        }
    }
}

class InstitutionalInvester implements Observer {
    private String name;
    private float maxPrice;
    private float minPrice;
    
    public InstitutionalInvester(String name, float maxPrice, float minPrice, Stock stock) {
        this.name = name;
        this.maxPrice = maxPrice;
        this.minPrice = minPrice;
        stock.addObserver(this);
    }
    
    @Override
    public void update(Observable o, Object arg) {
        float price = (Float)arg;
        if(price > maxPrice) {
            System.out.printf("%s is selling 100000 stocks...\n", name);
        }
        if(price < minPrice) {
            System.out.printf("%s is buying 20000 shares....\n", name);
        }
    }
}

class PrivateInvestor implements Observer {
    private String name;
    private float maxPrice;
    private float minPrice;
    
    public PrivateInvestor(String name, float maxPrice, float minPrice, Stock stock) {
        this.name = name;
        this.maxPrice = maxPrice;
        this.minPrice = minPrice;
        stock.addObserver(this);
    }
    
    @Override
    public void update(Observable o, Object arg) {
        float price = (Float)arg;
        if(price > maxPrice) {
            System.out.printf("%s is buying 500 stocks...\n", name);
        }
        if(price < minPrice) {
            System.out.printf("%s is selling 1000 shares....\n", name);
        }
    }
}
View Code

 

观察者模式

标签:

原文地址:http://www.cnblogs.com/programmer-kaima/p/4377119.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!