../guan-cha-zhe-mo-shi-shi-li-fen-xi

观察者模式实力分析

一般地,面向对象分析与设计中存在三种事件处理的机制,除了普通的函数调用外,常常用到回调函数,而 J2EE 中还提供了一种基于监听方式的事件处理机制,请查阅资料,对 Action 以及 ActionListener 的机制进行分析,完成一个分析实例。

首先了解观察者模式

观察者模式 (Observer Pattern)

真实世界中的观察者

观察者模式又称发布订阅模式,例如 RSS(微信推送的爸爸)订阅,某博客(被观察者)的博主在更新博文后,订阅者的阅读器(观察者)上就会自动能够收到更新。这种发布-订阅的套路我们称作观察者模式。

观察者模式

(Gang Of Four)对观察者模式的描述:

可以发现观察者模式常常应用于:

相比于普通的函数调用以及回调函数,观察者模式的使用能够做到低成本维持对象间一致性,大大降低了对象间的耦合关系程度,同时可以达到广播的效果,这是前二者做不到的。观察者模式的使用大大提高了代码的可重用性**。

而 J2EE 中的 Action 和 ActionListener 正是观察者模式的一个鲜活的例子。

J2EE 中的 Action&ActionListener

Action&ActionListener 可以很好地应用于 MVC 范式用来降低 model 和 view 的耦合程度。

找到一个很好的例子,代码如下所示:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class Frame extends JFrame {

  ActionListener observer1 = new Observer("First Observer");
  ActionListener observer2 = new Observer("Second Observer");
  ActionListener observer3 = new Observer("Third Observer");

  public Frame(){
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    init();
  }

  private void init(){
    addChangingTextField();
    pack();
    setVisible(true);
  }

  private void addChangingTextField(){
    //Observable class TextField. each time
    //An action or event occurs the observers will be updated
    //Almost all the Swing classes has this kind of behavior
    JTextField dataTextField = new JTextField();

    // Observer registering to the observable class.
    dataTextField.addActionListener(observer1);
    dataTextField.addActionListener(observer2);
    dataTextField.addActionListener(observer3);

    add(dataTextField);
  }

  public static void main(String [] args){
  	Frame frame = new Frame();
  }
}

class Observer implements ActionListener{

  private String name;
  private String message;

  public Observer (String s){
  	name = s;
  }

  public void actionPerformed(ActionEvent e) {
    JTextField textField = (JTextField) e.getSource();
    message = textField.getText();
    JOptionPane.showMessageDialog(null,
    name + " has been confirmed about the change, Thanks!! "
    + " The Message was: " + message);
  }
}

分析

两个类分别担任了 Action/ActionListener 的角色,frame.dataTextFieldaddChangingTextField方法中绑定了三个监听器(observer1, observer2, observer3),在 frame 中文本框被编辑后(状态改变),触发 Observer 中actionPerformed方法,显示相应文本。

在这个例子中,frame.dataTextField作为ConcreteSubjectobserver1, observer2, observer3作为ConcreteObserver。而他们所实现的定义了 Action/ActionListener 方法的接口,则是相应的SubjectObserver

在绑定观察者后目标并不关注观察者具体的行为,而只是在自身状态发生改变时通知观察者,由观察者自身决定做什么动作,因此这种方法就很 nice,比显式调用函数或者执行回调函数的方式触发动作不知道高到哪里去了,值得学习一个。

/设计模式/ /系统分析与设计/