⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 observe.txt

📁 这是用delphi编写的一些设计模式的样例
💻 TXT
字号:
 Observer模式的功用,是希望两个(或多个)对象,我们称之为Subject和Observer,
   当一方的状态发生改变的时候,另一方能够得到通知。也就是说,作为Observer的一方,
   能够监视到Subject的某个特定的状态变化,并为之做出反应。一个简单的例子就是:
   当一个用户视图中的数据被用户改变后,后端的数据库能够得到更新,
   而当数据库被其他方式更新后,用户视图中的数据显示也会随之改变。
 在JDK中实际上有一个对Observer模式的简单的实现:就是类java.util.Observerable和接口java.util.Observer。
    java.util.Observerable类对应于Subject,而java.util.Observer就是观察者了。JDK中并没有把这两个部分都
    设计为接口,而是让类java.util.Observerable提供了部分的实现,简化了许多编程的工作。当然,
     这也减少了一定的灵活性。

  下面列出了Observer和Observeral的函数列表,及其简单的功能说明

  java.util.Observer:

  public void update(Observable obs, Object obj)
  java.util.Observer 接口很简单,只定义了这一个方法,狭义的按照Observer模式的说法,
       Observer应该在这个方法中调用Subject的getXXX()方法来取得最新的状态,而实际上,
       你可以只是在其中对Subject的某些事件进行响应。这便是Java中的代理事件模型的一个
       雏形--对事件进行响应。只不过,在Observer模式中将事件特定化为某个状态/数据的改变了。

  java.util.Observable:

  public void addObserver(Observer obs)
  向Subject注册一个Observer。也就是把这个Observer对象添加到了一个java.util.Observable内部的列表中。
       在JDK中对于这个列表是简单的通过一个java.util.Vector类来实现的,而实际上,在一些复杂的Observer     
      模式的应用中,需要把这个部分单另出来形成一个Manager类,来管理Subject和Observer之间的映射。
      这样,Subject和Observer进一步的被解藕,程序也会具有更大的灵活性。

  public void deleteObserver(Observer obs)
  从Subject中删除一个已注册了Observer的引用。

  public void deleteObservers()
  从Subjec中删除所有注册的Observer的引用。

  public int countObservers()
  返回注册在Subject中的Observer个数。

  protected void setChanged()
  设置一个内部的标志以指明这个Ovserver的状态已经发生改变。注意这是一个protected方法,
        也就是说只能在Observer类和其子类中被调用,而在其它的类中是看不到这个方法的。

  protected void clearChanged()
  清除上叙的内部标志。它在notifyObservers()方法内部被自动的调用,以指明Subject的状态的改
       变已经传递到Ovserver中了。

  public boolean hasChanged()
  确定Subject的状态是否发生了改变。

  public void notifyObservers(Object obj)
  它首先检查那个内部的标志,以判断状态是否改变,如果是的话,它会调用注册在Subject中
       的每个Observer的update()方法。在JDK中这个方法内部是作为synchronized来实现的,也就是如果
       发生多个线程同时争用一个java.util.Observerable的notifyObservers()方法的话,他们必须按调度的
       等待着顺序执行。在某些特殊的情况下,这会有一些潜在的问题:可能在等待的过程中,一个
       刚刚被加入的Observer会被遗漏没有被通知到,而一个刚刚被删除了的Observer会仍然收到它已
       经不想要了的通知。

  public void notifyObservers()
  等价于调用了notifyObservers(null)。

  因而在Java中应用Observer就很简单了,需要做的是:让需要被观察的Subject对象继承
       java.util.Observerable,让需要观察的对象实现java.util.Observer接口,然后用java.util.Observerable的addObserver(Observer obj)方法把Observer注册到Subject对象中。这已经完成了大部分的工作了。然后调用java.util.Observerable的notifyObservers(Object arg)等方法,就可以实现Observer模式的机理。我们来看一个简单使用了这个模式的例子。这个例子有三个类:FrameSubject,DateSubject,FrameObject和EntryClass,FrameSubject中用户可以设置被观察的值,然后自动的会在FrameObject中显示出来,DateSubject封装被观察的值,并且充当Observer模式中的Subject。

 程序代码
public class FrameSubject extends JFrame {
…………
//因为无法使用多重继承,这儿就只能使用对象组合的方式来引入一个
//java.util.Observerable对象了。
DateSubject subject=new DateSubject();

//这个方法转发添加Observer消息到DateSubject。
public void registerObserver(java.util.Observer o){
subject.addObserver(o);
}

//数据改变,事件被触发后调用notifyObservers()来通知Observer。
void jButton1_actionPerformed(ActionEvent e) {
subject.setWidthInfo(Integer.parseInt(jTextField1.getText()));
subject.setHeightInfo(Integer.parseInt(jTextField2.getText()));
subject.notifyObservers();
}
……………
}

public class DateSubject extends Observable {

//封装被观察的数据
private int widthInfo;
private int heightInfo;

public int getWidthInfo() {
return widthInfo;
}

public void setWidthInfo(int widthInfo) {
this.widthInfo = widthInfo;
//数据改变后,setChanged()必须被调用,否则notifyObservers()方法会不起作用
this.setChanged();
}
public void setHeightInfo(int heightInfo) {
this.heightInfo = heightInfo;
this.setChanged();
}
public int getHeightInfo() {
return heightInfo;
}
}

public class FrameObserver extends JFrame implements java.util.Observer {
…………
//观察的数据
int widthInfo=0;
int heightInfo=0;

//在update()方法中实现对数据的更新和其它必要的反应。
public void update(Observable o, Object arg) {
DateSubject subject=(DateSubject) o;
widthInfo=subject.getWidthInfo();
heightInfo=subject.getHeightInfo();
jLabel1.setText("The heightInfo from subject is: ");
jLabel3.setText(String.valueOf(heightInfo));
jLabel2.setText("The widthInfo from subject is: ");
jLabel4.setText(String.valueOf(widthInfo));
}
……………
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -