菜鸟之路-浅谈设计模式之观察者模式
观察者模式
观察者模式(有时又被称为公布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中。一个目标物件管理全部相依于它的观察者物件,而且在它本身的状态改变时主动发出通知。
这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
基本简单介绍
观察者模式(Observer)完美的将观察者和被观察的对象分离开。
举个样例,用户界面能够作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后。就显示在界面上。
面向对象设计的一个原则是:系统中的每一个类将重点放在某一个功能上,而不是其它方面。
一个对象仅仅做一件事情,而且将他做好。
观察者模式在模块之间划定了清晰的界限。提高了应用程序的可维护性和重用性。
观察者设计模式定义了对象间的一种一对多的依赖关系。以便一个对象的状态发生变化时,全部依赖于它的对象都得到通知并自己主动刷新。
实现方式
观察者模式有非常多实现方式,从根本上说,该模式必须包括两个角色:观察者和被观察对象。在刚才的样例中,业务数据是被观察对象。用户界面是观察者。
观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这种变化,而且做出对应的响应。假设在用户界面、业务数据之间使用这种观察过程,能够确保界面和数据之间划清界限,假定应用程序的需求发生变化,须要改动界面的表现,仅仅须要又一次构建一个用户界面,业务数据不须要发生变化。
过程
实现观察者模式有非常多形式,比較直观的一种是使用一种“注冊——通知——撤销注冊”的形式。以下的图具体的描写叙述了这样一种过程:
观察者
(Observer)将自己注冊到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
被观察
被观察对象发生了某种变化(如图中的SomeChange),从容器中得到全部注冊过的观察者。将变化通知观察者。
撤销观察
观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。
观察者将自己注冊到被观察者的容器中时,被观察者不应该过问观察者的详细类型,而是应该使用观察者的接口。
这种长处是:假定程序中还有别的观察者,那么仅仅要这个观察者也是同样的接口实现就可以。
一个被观察者能够相应多个观察者。当被观察者发生变化的时候,他能够将消息一一通知给全部的观察者。
基于接口,而不是详细的实现——这一点为程序提供了更大的灵活性。
现实生活中的应用
比方像当当网、京东商城一类的电子商务站点,假设你对某件商品比較关注,能够放到收藏架,那么当该商品降价时,系统给您发送手
机短信或邮件。这就是观察者模式的一个典型应用,商品是被观察者。有的叫主体;关注该商品的客户就是观察者。
机短信或邮件。这就是观察者模式的一个典型应用,商品是被观察者。有的叫主体;关注该商品的客户就是观察者。
Java JDK里的观察者模式
在java的util包中实现了该设计模式的框架。大部分应用都能够直接用它,
当然了你也能够自己实现它。实际上就是一个被观察者的抽象类和一个观察者接口。我们先看一下jdk是怎样实现的。
当然了你也能够自己实现它。实际上就是一个被观察者的抽象类和一个观察者接口。我们先看一下jdk是怎样实现的。
先来看下被观察者的抽象类(大家自己也能够自己去看看源代码。为了整洁起见,里面的英文凝视被我删了)
public class Observable { private boolean changed = false; private Vector obs; /** Construct an Observable with zero Observers. */ public Observable() { obs = new Vector(); } public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); } }
public interface Observer { /** * This method is called whenever the observed object is changed. An * application calls an <tt>Observable</tt> object's * <code>notifyObservers</code> method to have all the object's * observers notified of the change. * * @param o the observable object. * @param arg an argument passed to the <code>notifyObservers</code> * method. */ void update(Observable o, Object arg); }
OK,接下来 我们自己来个样例让你对观察者模式瞬间清晰明了
小二,上菜
先写一个股票类继承自被观察者抽象类
import java.util.Observable; import java.util.Observer; /**股票类*/ public class GuPiao extends Observable{ private String GPName; private int price; public String getGPName() { return GPName; } public void setGPName(String gPName) { GPName = gPName; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public void modifyprice(GuPiao gp){ setChanged(); notifyObservers(gp); } }然后写两个实现了观察者接口的顾客类
import java.util.Observable; import java.util.Observer; /**顾客类1*/ public class Customer1 implements Observer{ private String customerName; private String type; public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public void update(Observable o, Object arg) { GuPiao gp=(GuPiao) arg; System.out.println(getType()+"的"+getCustomerName()+"购买的"+gp.getGPName()+"这仅仅股票,如今的价格为"+gp.getPrice()+"梦幻币"); } }
import java.util.Observable; import java.util.Observer; /**顾客类2*/ public class Customer2 implements Observer{ private String customerName; private String type; public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public void update(Observable o, Object arg) { GuPiao gp=(GuPiao) arg; System.out.println(getType()+"的"+getCustomerName()+"购买的"+gp.getGPName()+"这仅仅股票,如今的价格为"+gp.getPrice()+"梦幻币"); } }
调用类
public class JieMian { public static void main(String[] args) { //股票更新的价格 GuPiao gp=new GuPiao(); gp.setGPName("常青藤"); gp.setPrice(100); Customer1 customer1=new Customer1(); customer1.setCustomerName("红孩儿"); customer1.setType("魔族"); Customer2 customer2=new Customer2(); customer2.setCustomerName("剑侠客"); customer2.setType("人族"); gp.addObserver(customer1); gp.addObserver(customer2); //更新后提示观察者,也就是告诉顾客 gp.modifyprice(gp); } }
输出结果:
人族的剑侠客购买的常青藤这仅仅股票,如今的价格为100梦幻币
魔族的红孩儿购买的常青藤这仅仅股票,如今的价格为100梦幻币
魔族的红孩儿购买的常青藤这仅仅股票,如今的价格为100梦幻币
OK,朋友 相信你已经看懂了吧!
顶一个呗