观察者模式定义了一个一对多的对象关系:一个主体对象对应多个观察者对象。当主体对象发生改变时,所有它对应的观察者对象都会自动得到通知并更新。
本文将给出一个相应的事例具体说明观察者模式是如果工作的。这个事例演示了一个当一个任务的信息改变时通知这个任务所涉及所有人员的事例。任务信息包括任务状态,任务所采用的处理流程和任务完成后的checklist[用来确保任务完成所有预定需要完成的功能列表和避免一些常见的错误].
先定义两个接口:主体对象接口和观察者对象接口。
/** */
/**
* 主体对象接口定义了注册观察者,取消观察者和通知观察者方法。
*
*/
public
interface
ISubject
{
/** */
/**
* 为该主体对象注册一个观察者。
*/
public
void
registerObserver(IObserver observer);
/** */
/**
* 从该主体对象中取消一个观察者的注册。
*/
public
void
removeObserver(IObserver observer);
/** */
/**
* 通知所有观察者。
*/
public
void
notifyObserver();
}
/** */
/**
* 观察者接口简单定义了一个用来更新观察者信息的接口。
* 当主体对象被更新时,这个接口方法会被自动调用并更新信息。
*/
public
interface
IObserver
{
/** */
/**
* 接口方法用来更新观察者的信息。
*/
public
void
remind(ITask taskSubject);
}
这两个接口只定义了主题对象和观察者对象所需要的接口,但是没有实现任何任务相关的具体的方法和接口。下面会再定义一个任务接口来规定任务应该具备的功能。这样分开定义的好处在于,如果我们将不同的模块分解开来,如果一方需要更新,另一方不会受到影响。
/** */
/**
* 这里定义了一个任务应该具有的功能。
*/
public
interface
ITask
{
public
void
setStatus(String status);
public
String getStatus();
public
void
setProcess(String process);
public
String getProcess();
public
void
setCheckList(String checkList);
public
String getCheckList();
}
然后我们创建具体的任务主体。这里我们会实现ISubejct, ITask两个接口。
import
java.util.ArrayList;
import
java.util.List;
public
class
TaskSubject
implements
ISubject, ITask
{
//
在这里对观察者列表进行初始化。因为是静态初始化,所以保证在这个运行过程中只有一个实例得到初始化。
static
{
_observers
=
new
ArrayList
<
IObserver
>
();
}
@Override
public
void
notifyObserver()
{
//
调用观察者的方法通知并更新观察者信息。
for
(IObserver observer : _observers)
{
observer.remind(
this
);
}
}
@Override
public
void
registerObserver(IObserver observer)
{
if
(_observers.contains(observer))
{
System.out.println(
"
<
"
+
observer
+
"
> is already registed!
"
);
}
//
Register an observer
_observers.add(observer);
System.out.println(
"
<
"
+
observer
+
"
> is registed successfully!
"
);
}
@Override
public
void
removeObserver(IObserver observer)
{
if
(
!
_observers.contains(observer))
{
System.out.println(
"
<
"
+
observer
+
"
> is never registed!
"
);
}
//
Remove an observer
_observers.remove(observer);
System.out.println(
"
<
"
+
observer
+
"
> is removed successfully!
"
);
}
@Override
public
String getCheckList()
{
return
this
._checkList;
}
@Override
public
String getProcess()
{
return
this
._process;
}
@Override
public
String getStatus()
{
return
this
._status;
}
@Override
public
void
setCheckList(String checkList)
{
this
._checkList
=
checkList;
}
@Override
public
void
setProcess(String process)
{
this
._process
=
process;
}
@Override
public
void
setStatus(String status)
{
this
._status
=
status;
}
//
这里将观察者列表定义为一个静态的变量,这样可以保证自始至终只有一个变量列表,便于系统的维护。
//
这里用到了泛型,这样在对这个列表进行操作的时候,无需再进行类型的转换。
private
static
List
<
IObserver
>
_observers;
private
String _status;
private
String _process;
private
String _checkList;
}
在这里我们没有给观察者定义接口,而是使用了一个抽象类。因为所有的观察者都必须从主体对象那里获取信息,而且获取信息的方法都是一样的,这样可以避免重复编码。