- 作者:邹祁峰
- 邮箱:Qifeng.zou.job@hotmail.com
- 博客:http://blog.csdn.net/qifengzou
- 日期:2012.11.13
- 转载请注明来自"祁峰"的CSDN博客
1 概念定义
Strategy模式:是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。Strategy模式使得算法可以在不影响到客户端的情况下发生变化。Strategy模式把行为和环境分开。环境类负责维持和查询行为类,各种算法在具体的策略类中提供。由于算法和环境独立开来,算法的增减,修改都不会影响到环境和客户端。
2 模式结构图
图1 Strategy模式结构图
3 实用场景
假如现有一组访问Oracle数据库的接口、一组访问Informix数据库的接口、一组访问DB2数据库的接口。请设计和实现一组统一数据库访问的接口(UDBC)。
4 代码实现
// 结构定义(行为类)
// 回调指针结构体
typedef struct
{
int (*db_open)(void**);
int (*db_rollback)(void*);
int (*db_mquery(const char *, void*);
int (*db_nquery(const char *, void*);
...
}db_cb_ptr_t;
// 各组件接口(各组算法)
1. Oracle访问接口(第一组算法)
int db_ora_open(void **context){...}
int db_ora_rollback(void *context){...}
...
2. Informix访问接口(第二组算法)
int db_ifx_open(void **context){...}
int db_ifx_rollback(void *context){...}
...
3. DB2访问接口(第三组算法)
int db_db2_open(void **context){...}
int db_db2_rollback(void *context){...}
...
// 设置回调函数(维持和查询行为)
// 定义&声明回调对象
db_cb_ptr_t g_db_cb_ptr;
// 数据库初始化int db_init(db_type_t dbtype){ switch(dbtype) { case DB_TYPE_ORACLE: { // 设置Oracle回调 g_db_cb_ptr.db_open = db_ora_open; g_db_cb_ptr.db_close = db_ora_close; g_db_cb_ptr.db_rollback = db_ora_rollback; g_db_cb_ptr.db_commit = db_ora_commit; ... break; } case DB_TYPE_INFORMIX: { // 设置Inofrmix回调 g_db_cb_ptr.db_open = db_ifx_open; g_db_cb_ptr.db_close = db_ifx_close; g_db_cb_ptr.db_rollback = db_ifx_rollback; g_db_cb_ptr.db_commit = db_ifx_commit; ... break; } case DB_TYPE_DB2: { // 设置Db2回调 g_db_cb_ptr.db_open = db_db2_open; g_db_cb_ptr.db_close = db_db2_close; g_db_cb_ptr.db_rollback = db_db2_rollback; g_db_cb_ptr.db_commit = db_db2_commit; ... break; } case ...: { ... break; } } return 0;}
// UDBC接口(Strategy接口)
// 连接数据库
int db_open(void **context)
{
return g_db_cb_ptr.db_open(context);
}
//断开连接
int db_close(void *context)
{
return g_db_cb_ptr.db_open(context);
}
//事务回滚
int db_rollback(void *context)
{
return g_db_cb_ptr.db_rollback(context);
}
// 事务提交
int db_commit(void *context)
{
return g_db_cb_ptr.db_commit(context);
}
...
// Strategy接口的使用
int main(void)
{
void *context = NULL;
const char *sql = "INSERT INTO test_table VALUES(...)";
db_init(DB_TYPE_ORACLE);
db_open(&context);
db_nquery(sql, context);
db_close(context);
return 0;
}