Observer模式的问题

09-04-15 wing123
    

下面是我用Observer模式做例子,使用EnvetHandler类模仿.Net的事件委托机制,在该类中用一个List<EventHandler>来存储和遍历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<EventHandler> eventHandlers = new ArrayList<EventHandler>();

//观察者

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修改过]

    

banq
2009-04-16 09:13

其实你没有引入工厂模式。

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