設計模式應用之Observer模式(1)

husthxd發表於2005-06-06

關於observer模式的細節可以參考講述設計模式的書籍。其類圖如下所示:

http://blog.itpub.net/get/11/observer.jpg


Author:husthxd

From:www.itpub.net

Msn:

本例主要講述如何在專案中應用observer模式以滿足客戶的需求,客戶需求如下:
1. 稽核小組成員簽名是在專門的機器上,所有成員每人一臺機器坐在一起討論,討論完一起簽名確認。
2. 定義會議室中某幾臺機器為稽核小組討論所要使用的機器,其中一臺定義為主控機,有且只有一臺。
3. 在會議室專門的機器上登入了的使用者均為在此期間的稽核小組成員
4. 未被主控機器訪問的專案不視為進入稽核小組稽核狀態,已被主控機訪問稽核頁面的專案視為進入稽核狀態,並記錄當前在特定機器上登陸的使用者為該專案的稽核小組成員。
5. 若中途有使用者在特定的機器上登陸進入,則該使用者也成為當時進入稽核小組討論狀態但未審結的專案所對應的稽核小組中的一員。
6. 若中途有使用者退出系統,如存在已進入小組討論狀態但該使用者未簽名的專案,則在該使用者退出前提示該使用者有尚未簽名的條目,但可不簽名。該成員離開後,將不屬於當時已進入小組討論狀態專案的稽核小組成員,不需要該使用者簽名確認。

從需求我們可以看出,稽核小組是一個虛擬的概念,稽核小組成員是隨著使用者登陸和退出系統動態變化的,因而我們可以應用第二種方式的observer模式監聽使用者的登陸和退出從而觸發相應的事件。
ActionListener作為使用者登陸和退出的監聽介面,程式碼如下:
package test.pattern;

/**
* Description : 監聽器
* Author : husthxd
* 來自
www.itpub.net
* Date: 2005-6-3
* Time: 12:08:22
* Version 1.0
*/
public interface ActionListener {
//登陸
public void login(User user) throws CustomException;

//退出
public void logout(User user) throws CustomException;
}
ActionListener的實現類DefaultLogonListener,使用者在登陸和退出的時候在相應的表中記錄:
package test.pattern;

import org.apache.log4j.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Map;

/**
* Description :
* Author : husthxd
* 來自
www.itpub.net
* Date: 2005-6-3
* Time: 12:18:53
* Version 1.0
*/
public class DefaultLogonListener implements ActionListener {
static Logger logger = Logger.getLogger(DefaultLogonListener.class);
public DefaultLogonListener() {
}
//登陸
public void login(User user) throws CustomException {
Connection conn = null;
try {
//資料庫連線
conn = ConnMgr.getConnection();
conn.setAutoCommit(false);
//sql語句
StringBuffer sqlstmt = new StringBuffer();
//判斷使用者是否已經在表中
//構造sql語句
sqlstmt.append("select count(*) v_count from LOGIN_USER where USERID =");
sqlstmt.append(user.getUserId());
logger.debug("sql語句:" + sqlstmt);
//取得結果
Map map = BusinessLogicQueryHelper.factory().getRecord(conn, sqlstmt.toString());
int iCount = Integer.parseInt(map.get("v_count").toString());
if (iCount > 0) {
return;
}
//執行sql語句
sqlstmt.append("insert into LOGIN_USER values (?,?)");
PreparedStatement stmt = conn.prepareStatement(sqlstmt.toString());
//設定引數
stmt.setInt(1, user.getUserId());
stmt.setString(2, user.getUserName());
//執行
stmt.execute();
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
} catch (Exception e2) {
}
throw new CustomException("出錯!" + e);
} finally {
ConnMgr.closeConnection(conn);
}
}

//退出
public void logout(User user) throws CustomException {
Connection conn = null;
try {
//資料庫連線
conn = ConnMgr.getConnection();
conn.setAutoCommit(false);
StringBuffer sqlstmt = new StringBuffer();
//執行sql語句
sqlstmt.append("DELETE FROM LOGIN_USER WHERE USERID = ? ");
logger.debug("sql語句:" + sqlstmt);
PreparedStatement stmt = conn.prepareStatement(sqlstmt.toString());
stmt.setInt(1, user.getUserId());
//執行
stmt.execute();
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
} catch (Exception e2) {
}
throw new CustomException("出錯!" + e);
} finally {
ConnMgr.closeConnection(conn);
}
}
}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6906/viewspace-21823/,如需轉載,請註明出處,否則將追究法律責任。

相關文章