Observer模式的問題

wing123發表於2009-04-15
下面是我用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修改過]

相關文章