发帖    主题    评论    推荐    标签    作者    订阅    查搜    注册   登陆   关注
 
面向对象 设计模式 领域驱动设计 企业架构 框架 开发教程 微服务 大数据 扩展性 并发编程 事件驱动 分布式 SOA

Observer模式的问题

    
2009-04-15 08:25
赞助商链接

下面是我用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修改过]

2009-04-16 09:13

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

设计模式     

赞助商链接

赞助商链接

返回顶部

移动版 关于本站 使用帮助 联系管理员 最佳分辨率1366x768
OpenSource JIVEJDON Powered by JdonFramework Code © 2002-20 jdon.com