当前位置:编程学习 > JAVA >>

JAVA设计模式七--observer(观察者模式)

参与本模式的各类别列出如下。成员函式以模拟的方式列出。
抽象目标类别
此抽象类别提供一个接口让观察者进行添附与解附作业。此类别内有个不公开的观察者串炼,并透过下列函式(方法)进行作业
添附(Attach):新增观察者到串炼内,以追踪目标物件的变化。
解附(Detach):将已经存在的观察者从串炼中移除。
通知(Notify):利用观察者所提供的更新函式来通知此目标已经产生变化。
添附函式包涵了一个观察者物件参数。也许是观察者类别的虚拟函式(即更新函式),或是在非面向对象的设定中所使用的函式指标(
更广泛来讲,函式子或是函式物件)。
目标类别
此类别提供了观察者欲追踪的状态。也利用其源类别(例如前述的抽象目标类别)所提供的方法,来通知所有的观察者其状态已经更新。
此类别拥有以下函式
取得状态(GetState):回传该目标物件的状态。
抽象观察者接口
抽象观察者类别是一个必须被实做的抽象类别。这个类别定义了所有观察者都拥有的更新用接口,此接口是用来接收目标类别所发出的
更新通知。此类别含有以下函式
更新(Update):会被实做的一个抽象(虚拟)函式。
观察者类别
这个类别含有指向目标类别的参考(reference),以接收来自目标类别的更新状态。此类别含有以下函式
更新(Update):是前述抽象函式的实做。当这个函式被目标物件呼叫时,观察者物件将会呼叫目标物件的取得状态函式,来其所拥有
的更新目标物件资讯。每个观察者类别都要实做它自己的更新函式,以应对状态更新的情形。
当目标物件改变时,会通过呼叫它自己的通知函式来将通知送给每一个观察者物件,这个通知函式则会去呼叫已经添附在串炼
内的观察者更新函式。通知与更新函式可能会有一些参数,好指明是目前目标物件内的何种改变。这么作将可增进观察者的效率
(只更新那些改变部份的状态)。


用途


当抽象个体有两个互相依赖的层面时。封装这些层面在单独的物件内将可允许程式设计师单独地去变更与重复使用这些物件,而不
会产生两者之间交互的问题。
当其中一个物件的变更会影响其他物件,却又不知道多少物件必须被同时变更时。
当物件应该有能力通知其他物件,又不应该知道其他物件的实做细节时。
观察者模式通常与 MVC 范式有关系。在 MVC 中,观察者模式被用来降低 model 与 view 的耦合程度。一般而言, model
的改变会触发通知其他身为观察者的 model 。而这些 model 实际上是 view 。 Java Swing 就是个范例,示意了 model
预期会透过 PropertyChangeNotification 架构以送出改变的通知给其他 view 。 Model 类别是 Java bean 类别的一员
,并拥有与上述目标类别同样的行为。 View 类别则系结了一些 GUI 中的可视元素,并拥有与上述观察者类别同样的行为。
当应用程式在执行时。使用者将因 view 做出相应的更新而看见 model 所产生的变更。
如图:


举例说明:
[java] 
package design.observer; 
/**
 * 文件名称:design.singleton.Singleton.java
 * 创建人:Fei Wong
 * 创建时间: 2012-06-20
 * 电子邮箱:www.zzzyk.com
 * 说明:观察者
 * */ 
public interface Observer { 
     void update(NumberGenerator generator);   

 
 
package design.observer; 
 
import java.util.ArrayList;   
import java.util.Iterator;   
 
/**
 * 文件名称:design.singleton.Singleton.java
 * 创建人:Fei Wong
 * 创建时间: 2012-06-20
 * 电子邮箱:www.zzzyk.com
 * 说明:产生数值的抽象类 
 * */ 
public abstract class NumberGenerator {   
    private ArrayList<Observer> observers = new ArrayList<Observer>();  //存储Observer   
    /** 添加观察者*/   
    public void addObserver(Observer observer) { 
        observers.add(observer);   
    }   
    /** 删除观察者*/   
    public void delObserver(Observer observer) {   
        observers.remove(observer);   
    }   
    /** 通知所有观察者*/   
    public void notifyObservers() {   
        Iterator<Observer> it = observers.iterator() ; 
        while(it.hasNext()) {   
            Observer o =(Observer) it.next();   
            o.update(this);//this相当于上面提到的邮局名 
        } 
    } 
    public abstract int getNumber();//获取数字   
    public abstract void generate();//产生数字  
}  
 
 
package design.observer; 
 
import java.util.ArrayList;   
import java.util.Iterator;   
 
/**
 * 文件名称:design.singleton.Singleton.java
 * 创建人:Fei Wong
 * 创建时间: 2012-06-20
 * 电子邮箱:www.zzzyk.com
 * 说明:产生数值的抽象类 
 * */ 
public abstract class NumberGenerator {   
    private ArrayList<Observer> observers = new ArrayList<Observer>();  //存储Observer   
    /** 添加观察者*/   
    public void addObserver(Observer observer) { 
        observers.add(observer);   
    }   
    /** 删除观察者*/   
    public void delObserver(Observer observer) {   
        observers.remove(observer);   
    }   
    /** 通知所有观察者*/   
    public void notifyObservers() {   
        Iterator<Observer> it = observers.iterator() ; 
        while(it.hasNext()) {   
            Observer o =(Observer) it.next();   
            o.update(this);//this相当于上面提到的邮局名 
        } 
    } 
    public abstract int getNumber();//获取数字   
    public abstract void generate();//产生数字  
}  
 
package design.observer; 
 
/**
 * 文件名称:design.singleton.Singleton.java
 * 创建人:Fei Wong
 * 创建时间: 2012-06-20
 * 电子邮箱:www.zzzyk.com
 * 说明:以数字表示观察者的类
 * */ 
public class NumberObserver implements Observer { 
 
    @Override 
    public void update(NumberGenerator generator) { 
        System.out.println("NumberObserver:" + generator.getNumber()); 
        try { 
            Thread.sleep(1000 * 3); // 为了能清楚的看到输出,休眠3秒钟。 
        } catch (InterruptedException e) { <

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,