Observer模式的問題
下面是我用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實況,繼續工作!
問題:
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:看了你的設計模式:Observer,有些疑問設計模式Server
- 設計模式----Observer模式設計模式Server
- 應用Observer介面實踐Observer模式Server模式
- Java:應用Observer介面實踐Observer模式薦JavaServer模式
- 請教一個observer設計問題。Server
- 設計模式:觀察者模式(observer)設計模式Server
- observer-觀察者模式Server模式
- Visitor模式和Observer觀察者模式模式Server
- 設計模式應用之Observer模式(2)設計模式Server
- 設計模式應用之Observer模式(1)設計模式Server
- 看了設計模式之Observer設計模式Server
- banq 你好,請教Observer模式Server模式
- 設計模式之觀察者模式(Observer Pattern)設計模式Server
- 對 Observer進行包裝,遇到一些問題Server
- 談 C++17 裡的 Observer 模式 - 補C++Server模式
- 原生實現的觀察者模式(Observer Model)模式Server
- 談 C++17 裡的 Observer 模式 - 3C++Server模式
- 剪貼簿中的觀察者(Observer)模式Server模式
- Java Q&A: 使用Observer模式 (轉)JavaServer模式
- Java中使用Observer介面和Observable類實踐Observer觀察者模式JavaServer模式
- 人人都會設計模式—觀察者模式–Observer設計模式Server
- 人人都會設計模式---觀察者模式--Observer設計模式Server
- C#設計模式系列:觀察者模式(Observer)C#設計模式Server
- 談 C++17 裡的 Observer 模式 - 4 - 訊號槽模式C++Server模式
- Head First 設計模式(2)---觀察者(Observer)模式設計模式Server
- 設計模式-- 觀察者模式Observer(物件行為型)設計模式Server物件
- C#設計模式(17)——觀察者模式(Observer Pattern)C#設計模式Server
- 實現觀察者模式(Observer Pattern)的2種方式模式Server
- Java23種設計模式【22】----》觀察者模式(Observer)Java設計模式Server
- 設計模式(三)觀察者模式Observer(釋出訂閱)設計模式Server
- 重構到觀察者模式 Refactor to Observer Pattern模式Server
- 單例模式和多例模式問題得一個問題!單例模式
- 關於橋模式的問題模式
- 設計模式之間互為陷阱的問題!為模式而模式的疑問!設計模式
- 我工作的那點事--學習《設計模式》例項應用(Observer模式)設計模式Server
- 字串匹配模式問題字串匹配模式
- react history模式下的白屏問題React模式
- 嚴格模式下this的指向問題模式