观察者模式定义了一个一对多的对象关系一个主体对象对应多个观察者对象当主体对象发生改变时所有它对应的观察者对象都会自动得到通知并更新 本文将给出一个相应的事例具体说明观察者模式是如果工作的这个事例演示了一个当一个任务的信息改变时通知这个任务所涉及所有人员的事例任务信息包括任务状态任务所采用的处理流程和任务完成后的checklist[用来确保任务完成所有预定需要完成的功能列表和避免一些常见的错误] 先定义两个接口主体对象接口和观察者对象接口 /***//** *主体对象接口定义了注册观察者取消观察者和通知观察者方法 * */ publicinterfaceISubject{ /***//** *为该主体对象注册一个观察者 */ publicvoidregisterObserver(IObserverobserver); /***//** *从该主体对象中取消一个观察者的注册 */ publicvoidremoveObserver(IObserverobserver); /***//** *通知所有观察者 */ publicvoidnotifyObserver(); } /***//** *观察者接口简单定义了一个用来更新观察者信息的接口 *当主体对象被更新时这个接口方法会被自动调用并更新信息 */ publicinterfaceIObserver{ /***//** *接口方法用来更新观察者的信息 */ publicvoidremind(ITasktaskSubject); } 这两个接口只定义了主题对象和观察者对象所需要的接口但是没有实现任何任务相关的具体的方法和接口下面会再定义一个任务接口来规定任务应该具备的功能这样分开定义的好处在于如果我们将不同的模块分解开来如果一方需要更新另一方不会受到影响 /***//** *这里定义了一个任务应该具有的功能 */ publicinterfaceITask{ publicvoidsetStatus(Stringstatus); publicStringgetStatus(); publicvoidsetProcess(Stringprocess); publicStringgetProcess(); publicvoidsetCheckList(StringcheckList); publicStringgetCheckList(); } 然后我们创建具体的任务主体这里我们会实现ISubejct ITask两个接口 importjavautilArrayList; importjavautilList; publicclassTaskSubjectimplementsISubjectITask{ //在这里对观察者列表进行初始化因为是静态初始化所以保证在这个运行过程中只有一个实例得到初始化 static{ _observers=newArrayList<IObserver>(); } @Override publicvoidnotifyObserver(){ //调用观察者的方法通知并更新观察者信息 for(IObserverobserver:_observers){ observerremind(this); } } @Override publicvoidregisterObserver(IObserverobserver){ if(ntains(observer)){ Systemoutprintln(<+observer+>isalreadyregisted!); } //Registeranobserver _observersadd(observer); Systemoutprintln(<+observer+>isregistedsuccessfully!); } @Override publicvoidremoveObserver(IObserverobserver){ if(!ntains(observer)){ Systemoutprintln(<+observer+>isneverregisted!); } //Removeanobserver _observersremove(observer); Systemoutprintln(<+observer+>isremovedsuccessfully!); } @Override publicStringgetCheckList(){ returnthis_checkList; } @Override publicStringgetProcess(){ returnthis_process; } @Override publicStringgetStatus(){ returnthis_status; } @Override publicvoidsetCheckList(StringcheckList){ this_checkList=checkList; } @Override publicvoidsetProcess(Stringprocess){ this_process=process; } @Override publicvoidsetStatus(Stringstatus){ this_status=status; } //这里将观察者列表定义为一个静态的变量这样可以保证自始至终只有一个变量列表便于系统的维护 //这里用到了泛型这样在对这个列表进行操作的时候无需再进行类型的转换 privatestaticList<IObserver>_observers; privateString_status; privateString_process; privateString_checkList; } 在这里我们没有给观察者定义接口而是使用了一个抽象类因为所有的观察者都必须从主体对象那里获取信息而且获取信息的方法都是一样的这样可以避免重复编码 /***//** *这个抽象类继承了Iobserver接口所以我们必须实现remind方法 *在remind方法中从主体对象中获取所有需要的信息 *并调用sendEmail方法对观察者实时进行更新 */ publicabstractclassTaskObserverimplementsIObserver{ @Override publicvoidremind(ITasktaskSubject){ this_status=taskSubjectgetStatus(); this_process=taskSubjectgetProcess(); this_checkList=taskSubjectgetCheckList(); //更新观察者对象 thissendEmail(); } publicabstractvoidsendEmail(); //工具类方法减少编码数量增加可读性 publicvoidprint(Stringmsg){ Systemoutprintln(msg); } //在父类中定义参数减少重复编码 protectedString_status; protectedString_process; protectedString_checkList; } 然后定义任务受托人[assignee]检查者报告者他们都继承TaskObserver类这样减少了代码的重复而且方便了代码的维护 publicclassAssigneeextendsTaskObserver{ @Override publicvoidsendEmail(){ print([Assignee]Thecurrentstatusis:<+this_status+>); print([Assignee]Thecurrentprocessis:<+this_process+>); print([Assignee]Thecurrentchecklistis:<+this_checkList+>); } publicStringtoString(){ returnAssignee; } } publicclassReviewerextendsTaskObserver{ @Override publicvoidsendEmail(){ print([Reviewer]Thecurrentstatusis:<+this_status+>); print([Reviewer]Thecurrentprocessis:<+this_process+>); print([Reviewer]Thecurrentchecklistis:<+this_checkList+>); } publicStringtoString(){ returnReviewer; } } publicclassReporterextendsTaskObserver{ @Override publicvoidsendEmail(){ print([Reporter]Thecurrentstatusis:<+this_status+>); print([Reporter]Thecurrentprocessis:<+this_process+>); print([Reporter]Thecurrentchecklistis:<+this_checkList+>); } publicStringtoString(){ returnReporter; } } 然后我们需要编写一个类用来演示观察者模式在这个类中会演示注册观察者取消特定观察者更改主体对象信息然后观察者自动得到通知并更新信息 publicclassTaskManager{ publicstaticvoidmain(String[]args){ //Createsubject TaskSubjecttaskSubject=newTaskSubject(); //Createobservers IObserverassignee=newAssignee(); IObserverreviewer=newReviewer(); IObserverreporter=newReporter(); //注册观察者[因为我们使用的是一个列表所以在通知观察者的时候是按照添加的顺序通知的] taskSubjectregisterObserver(assignee); taskSubjectregisterObserver(reviewer); taskSubjectregisterObserver(reporter); //更新主体对象的信息 taskSubjectsetStatus(Assigned); taskSubjectsetProcess(NoProcessAttacted); taskSubjectsetCheckList(CheckListVersion); //通知所有观察者 taskSubjectnotifyObserver(); //更新主体对象信息 taskSubjectsetStatus(InProgress); taskSubjectsetProcess(ProcessAttached); taskSubjectsetCheckList(CheckListVersionFinalVersion); //取消报告者的注册并通知剩余所有观察者 taskSubjectremoveObserver(reporter); taskSubjectnotifyObserver(); } } 输出的信息如下 <Assignee>isregistedsuccessfully! <Reviewer>isregistedsuccessfully! <Reporter>isregistedsuccessfully! [Assignee]Thecurrentstatusis:<Assigned> [Assignee]Thecurrentprocessis:<NoProcessAttacted> [Assignee]Thecurrentchecklistis:<CheckListVersion> [Reviewer]Thecurrentstatusis:<Assigned> [Reviewer]Thecurrentprocessis:<NoProcessAttacted> [Reviewer]Thecurrentchecklistis:<CheckListVersion> [Reporter]Thecurrentstatusis:<Assigned> [Reporter]Thecurrentprocessis:<NoProcessAttacted> [Reporter]Thecurrentchecklistis:<CheckListVersion> <Reporter>isremovedsuccessfully! [Assignee]Thecurrentstatusis:<InProgress> [Assignee]Thecurrentprocessis:<ProcessAttached> [Assignee]Thecurrentchecklistis:<CheckListVersionFinalVersion> [Reviewer]Thecurrentstatusis:<InProgress> [Reviewer]Thecurrentprocessis:<ProcessAttached> [Reviewer]Thecurrentchecklistis:<CheckListVersionFinalVersion> |