Observer模式的问题

下面是我用Observer模式做例子,使用EnvetHandler类模仿.Net的事件委托机制,在该类中用一个List来存储和遍历EventHandler来通知具体的Observer类并调用Observer类中的相应方法,程序的基本工能是实现了。

问题:

1、 在创建观察对象(Boss/Secretary)时,需要new 一个EventHandler出来,以便使用它的List,这样就多了一块内存的开销,如何解决?

2、 根据依赖倒转原则,程序应面向接口编程,在Client中直接 Boss boss = new Boss(); 违反了原则,使用Informer boss = new Boss(); Boss 中的EventHandler引用又无法使用,如何解决?

3、 就是在写程序时,总是有许多问题,思路混乱,想不清楚问题出在哪,又不知道从哪里入手,请大家指点一下

以下是具体程序:

例:

同事上班偷懒,老板回来时需要 1、 前台进行“老板回来了”的通知 2、 前台来不及通知,老板自己进行“老板回来了”的通知

代码: public class StockObserver { private String name; private Informer informer; public StockObserver(String name, Informer informer) { this.name = name; this.informer = informer; } public void closeStockMark() { System.out.println(informer.state + " " + name + " 关闭股市行情,继续工作!"); } } public class NBAObserver { private String name; private Informer informer; public NBAObserver(String name, Informer informer) { this.name = name; this.informer = informer; } public void closeNBADirectSeeding() { System.out.println(informer.state + " " + name + " 关闭NBA实况,继续工作!"); } } public interface Informer { public static final String state = "老板回来了"; public void eventNotify(); } public class Secretary implements Informer { private EventHandler eventHandler = new EventHandler(); public void eventNotify() { eventHandler.eventNofity(); } public void addEventHandler(EventHandler eh) { eventHandler.eventHandlers.add(eh); } } public class Boss implements Informer { private EventHandler eventHandler = new EventHandler(); public void eventNotify() { eventHandler.eventNofity(); } public void addEventHandler(EventHandler eh) { eventHandler.eventHandlers.add(eh); } }

public class EventHandler { //当添加了多个观察者时,内部遍历使用 public List eventHandlers = new ArrayList(); //观察者 private Object observer; //观察者中相应的方法 private String methodName; /**

  • 构造函数
  • @param observer 观察者
  • @param methodName 观察者中相应的方法
*/ public EventHandler(Object observer, String methodName) { this.observer = observer; this.methodName = methodName; } public EventHandler() { } /**
  • 内部遍历事件处理委托方法
*/ public void eventNofity() { for(EventHandler eventHandler : eventHandlers) { eventHandler.update(); } } /**
  • 事件处理委托方法
*/ public void update() { //返回observer对象在运行时的class Class clazz = this.observer.getClass(); try { //得到指定委托方法的类型 Method method = clazz.getMethod(this.methodName, new Class[]{}); //调用指定的方法 method.invoke(this.observer, new Object[]{}); } catch (SecurityException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } public class Client { public static void main(String[] args) { //前台 Secretary s = new Secretary(); //看股市的员工 StockObserver stock = new StockObserver("TomStock",s); //添加观察者 s.addEventHandler(new EventHandler(stock,"closeStockMark")); System.out.println("前台报告:"); s.eventNotify(); System.out.println(); // 老板 Boss boss = new Boss(); // 看股市的员工 StockObserver so = new StockObserver("TomStock",boss); // 看NBA的员工 NBAObserver NBAo = new NBAObserver("JimNBA",boss); boss.addEventHandler(new EventHandler(so,"closeStockMark")); boss.addEventHandler(new EventHandler(NBAo,"closeNBADirectSeeding")); System.out.println("老板自己报告:"); boss.eventNotify(); } } 运行结果:

前台报告: 老板回来了 TomStock 关闭股市行情,继续工作!

老板自己报告: 老板回来了 TomStock 关闭股市行情,继续工作! 老板回来了 JimNBA 关闭NBA实况,继续工作! [该贴被admin于2009-04-16 09:13修改过]

其实你没有引入工厂模式。 将EventHandler创建使用工厂实现,Secretary 等业务类创建以及加入EventHandler也在工厂中实现,最好Secretary几个业务类统一一个接口,这样,客户端就不管工厂里获得的是Secretary或Boss其他。