Observer概述

Observer - 图1

UML概述

Observer - 图2

玩具代码案例1 - 模式监听一个数据迁移过程中的事件

事件的管理器

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.provider;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. import online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api.IMigrateListener;
  4. import online.javabook.gof.behavioral.patterns9.template1.migrate.template.IConnector;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class MigrateListenerProvider {
  8. private List<IMigrateListener> listeners = new ArrayList<>();
  9. public void addListener(IMigrateListener listener) {
  10. listeners.add(listener);
  11. }
  12. public void removeListener(IMigrateListener listener) {
  13. listeners.remove(listener);
  14. }
  15. public void onStartMigrate(IConnector sourceConnector, IConnector targetConnector) {
  16. for (IMigrateListener listener : listeners){
  17. try {
  18. listener.onStartMigrateTask(new MigrateEvent(sourceConnector, targetConnector));
  19. }catch (Exception e){
  20. System.out.println(e);
  21. }
  22. }
  23. }
  24. public void onPrepMigrateRow(IConnector sourceConnector, IConnector targetConnector, String row) {
  25. for (IMigrateListener listener : listeners){
  26. try {
  27. listener.onPrepMigrateRecord(new MigrateEvent(sourceConnector, targetConnector, row));
  28. }catch (Exception e){
  29. System.out.println(e);
  30. }
  31. }
  32. }
  33. public void onPostMigrateRow(IConnector sourceConnector, IConnector targetConnector, String row) {
  34. for (IMigrateListener listener : listeners){
  35. try {
  36. listener.onPostMigrateRecord(new MigrateEvent(sourceConnector, targetConnector, row));
  37. }catch (Exception e){
  38. System.out.println(e);
  39. }
  40. }
  41. }
  42. public void onFailMigrateRow(IConnector sourceConnector, IConnector targetConnector, String row, Exception exception) {
  43. for (IMigrateListener listener : listeners){
  44. try {
  45. listener.onFailMigrateRecord(new MigrateEvent(sourceConnector, targetConnector, row, exception));
  46. }catch (Exception e){
  47. System.out.println(e);
  48. }
  49. }
  50. }
  51. public void onFinishMigrate(IConnector sourceConnector, IConnector targetConnector) {
  52. for (IMigrateListener listener : listeners){
  53. try {
  54. listener.onFinishMigrateTask(new MigrateEvent(sourceConnector, targetConnector));
  55. }catch (Exception e){
  56. System.out.println(e);
  57. }
  58. }
  59. }
  60. }

事件的观察者

观察数据迁移任务过程中的每一个时间点发生的事件,这样很好的将额外的业务逻辑从主线逻辑中分离了

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. public interface IMigrateListener {
  4. void onStartMigrateTask(MigrateEvent event);
  5. void onPrepMigrateRecord(MigrateEvent event);
  6. void onPostMigrateRecord(MigrateEvent event);
  7. void onFailMigrateRecord(MigrateEvent event);
  8. void onFinishMigrateTask(MigrateEvent event);
  9. }

默认的适配器

在一个观察者模式中往往会配合默认适配器模式的使用

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. public class DefaultMigrateAdapterListener implements IMigrateListener {
  4. @Override
  5. public void onStartMigrateTask(MigrateEvent event) {
  6. }
  7. @Override
  8. public void onPrepMigrateRecord(MigrateEvent event) {
  9. }
  10. @Override
  11. public void onPostMigrateRecord(MigrateEvent event) {
  12. }
  13. @Override
  14. public void onFailMigrateRecord(MigrateEvent event) {
  15. }
  16. @Override
  17. public void onFinishMigrateTask(MigrateEvent event) {
  18. }
  19. }

观察者的实现

MigrateTaskListener

数据迁移任务的开始与结束时的监听器

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.listener.impl;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. import online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api.DefaultMigrateAdapterListener;
  4. public class MigrateTaskListener extends DefaultMigrateAdapterListener {
  5. @Override
  6. public void onStartMigrateTask(MigrateEvent event) {
  7. System.out.println("onStartMigrate -> start migrate task");
  8. }
  9. @Override
  10. public void onFinishMigrateTask(MigrateEvent event) {
  11. System.out.println("onFinishMigrate -> finish migrate task");
  12. }
  13. }

MigrateRecordListener

数据迁移单条记录时候的监听器

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.listener.impl;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. import online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api.DefaultMigrateAdapterListener;
  4. public class MigrateRecordListener extends DefaultMigrateAdapterListener {
  5. @Override
  6. public void onPrepMigrateRecord(MigrateEvent event) {
  7. System.out.println("onPrepMigrateRecord -> migrate row:" + event.getCurrentRow() + " to mysql");
  8. }
  9. @Override
  10. public void onPostMigrateRecord(MigrateEvent event) {
  11. System.out.println("onPostMigrateRow -> migrate row:" + event.getCurrentRow() + " to mysql");
  12. }
  13. }

MigrateMessageListener

数据迁移任务在开始与结束时的消息通知监听器

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.listener.impl;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. import online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api.DefaultMigrateAdapterListener;
  4. public class MigrateMessageListener extends DefaultMigrateAdapterListener {
  5. @Override
  6. public void onStartMigrateTask(MigrateEvent event) {
  7. System.out.println("onStartMigrate -> start migrate email notification");
  8. }
  9. @Override
  10. public void onFinishMigrateTask(MigrateEvent event) {
  11. System.out.println("onFinishMigrate -> finish migrate email notification");
  12. }
  13. }

MigrateExceptionListener

数据迁移记录时候的异常处理

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.listener.impl;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. import online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api.DefaultMigrateAdapterListener;
  4. public class MigrateExceptionListener extends DefaultMigrateAdapterListener {
  5. @Override
  6. public void onFailMigrateRecord(MigrateEvent event) {
  7. System.out.println("onFailMigrateRecord -> migrate row:" + event.getCurrentRow() + " to mysql fail:" + event.getException());
  8. }
  9. }

MigrateLoggerListener

数据迁移中在合适的事件点添加日志

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.listener.impl;
  2. import online.javabook.gof.behavioral.patterns6.observer.migrate.event.MigrateEvent;
  3. import online.javabook.gof.behavioral.patterns6.observer.migrate.listener.api.DefaultMigrateAdapterListener;
  4. public class MigrateLoggerListener extends DefaultMigrateAdapterListener {
  5. @Override
  6. public void onStartMigrateTask(MigrateEvent event) {
  7. System.out.println("onStartMigrate -> log start migrate task");
  8. }
  9. @Override
  10. public void onPrepMigrateRecord(MigrateEvent event) {
  11. System.out.println("onPrepMigrateRow -> log prep migrate record:" + event.getCurrentRow());
  12. }
  13. @Override
  14. public void onPostMigrateRecord(MigrateEvent event) {
  15. System.out.println("onPostMigrateRow -> log post migrate record:" + event.getCurrentRow());
  16. }
  17. @Override
  18. public void onFailMigrateRecord(MigrateEvent event) {
  19. System.out.println("onFailMigrateRow -> log fail migrate record:" + event.getCurrentRow());
  20. }
  21. @Override
  22. public void onFinishMigrateTask(MigrateEvent event) {
  23. System.out.println("onFinishMigrate -> log finish migrate task");
  24. }
  25. }

事件对象

MigrateEvent

事件中往往封装了程序运行时的上下文信息

  1. package online.javabook.gof.behavioral.patterns6.observer.migrate.event;
  2. import online.javabook.gof.behavioral.patterns9.template1.migrate.template.IConnector;
  3. public class MigrateEvent {
  4. private IConnector sourceConnector;
  5. private IConnector targetConnector;
  6. private String currentRow;
  7. private Exception exception;
  8. public MigrateEvent(IConnector sourceConnector, IConnector targetConnector) {
  9. this.sourceConnector = sourceConnector;
  10. this.targetConnector = targetConnector;
  11. }
  12. public MigrateEvent(IConnector sourceConnector, IConnector targetConnector, String currentRow) {
  13. this.sourceConnector = sourceConnector;
  14. this.targetConnector = targetConnector;
  15. this.currentRow = currentRow;
  16. }
  17. public MigrateEvent(IConnector sourceConnector, IConnector targetConnector, String currentRow, Exception exception) {
  18. this.sourceConnector = sourceConnector;
  19. this.targetConnector = targetConnector;
  20. this.currentRow = currentRow;
  21. this.exception = exception;
  22. }
  23. public IConnector getSourceConnector() {
  24. return sourceConnector;
  25. }
  26. public IConnector getTargetConnector() {
  27. return targetConnector;
  28. }
  29. public String getCurrentRow() {
  30. return currentRow;
  31. }
  32. public Exception getException() {
  33. return exception;
  34. }
  35. }