您的位置:首页 > 其它

设计模式 : 带2个参数的简单工厂

2018-01-29 14:47 218 查看

前言

工程里有一段数据的处理代码,要分许多case进行处理,想整个简单工厂来处理。

书上的例子,都是1个参数的。简单工厂有2个入参,该咋弄好些?

想来想去,就一个工厂类了,不继续在工厂类的内部再弄工厂类了。参数1引起的switch-case在工厂类的接口里面直接处理,参数2引起的switch-case, 放在工厂类的成员函数里面处理。

new出来的是数据处理类指针,在程序活着的时候,一种case只需要一个数据处理类.

将new出来的数据处理类指针,根据2个入参合并成一个map-key, 将指针压入map.

当调用者再请求数据类指针时,先合成map-key, 去map中去找,如果有就返回已有的数据处理类指针。如果没找到指定map-key的数据处理类指针,再去new数据处理类。

在程序退出时,调用工厂类的destory方法,进行资源释放。

工程下载点

src_test_data_factory.zip

工程预览

// @file \testcase\test_data_factory\data_factory.cpp

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

#include "MY_data_process_factory.h"

void test_data_factory();

int main(int argc, char** argv)
{
test_data_factory();

// when prog end, free resource
MY_data_process_factory::detory();

printf("END\n");
_getch();
return 0;
}

void test_data_factory()
{
int i = 0;
unsigned int ui_rc = MY_DATA_PROCESS_ERR;
MY_data_process_base* process_er = NULL;

do {
process_er = MY_data_process_factory::create_processer(DATA_TYPE_A, DATA_DIRECTION_RIGHT);
if (NULL != process_er) {
ui_rc = process_er->process((const unsigned char*)"hello world", (int)strlen("hello world"));
}

printf("* data process %s\n", (ui_rc == MY_DATA_PROCESS_OK) ? "ok" : "error");
} while (++i < 3);

process_er = MY_data_process_factory::create_processer(DATA_TYPE_B, DATA_DIRECTION_DOWN);
if (NULL != process_er) {
ui_rc = process_er->process((const unsigned char*)"hello world", (int)strlen("hello world"));
}

printf("** data process %s\n", (ui_rc == MY_DATA_PROCESS_OK) ? "ok" : "error");
}


// @file : \test_data_factory\MY_data_process_factory.h
// @brief : ...
#ifndef ___TEST_DATA_FACTORY_MY_DATA_PROCESS_FACTORY_H__
#define ___TEST_DATA_FACTORY_MY_DATA_PROCESS_FACTORY_H__

#include <map>

#include "MY_data_process_base.h"

// 假设这是俄罗斯方块的处理逻辑

// 当前方块的类型(S型, L型)
enum DATA_TYPE {
DATA_TYPE_UNKNOWN = -1,
DATA_TYPE_A,
DATA_TYPE_B,
};

// 当前方块的的相对运动方向(上,下,左,右)
enum DATA_DIRECTION {
DATA_DIRECTION_UNKNOWN = -1,
DATA_DIRECTION_UP,
DATA_DIRECTION_DOWN,
DATA_DIRECTION_LEFT,
DATA_DIRECTION_RIGHT
};

/*
处理各种情况的子类名称, 组合情况(DATA_TYPE)2 * (DATA_DIRECTION)4, base class MY_data_process_base
MY_data_process_TYPE_A_DIR_UP
MY_data_process_TYPE_A_DIR_DOWN
MY_data_process_TYPE_A_DIR_LEFT
MY_data_process_TYPE_A_DIR_RIGHT

MY_data_process_TYPE_B_DIR_UP
MY_data_process_TYPE_B_DIR_DOWN
MY_data_process_TYPE_B_DIR_LEFT
MY_data_process_TYPE_B_DIR_RIGHT
*/

class MY_data_process_factory
{
// 静态方法和成员(工厂类使用)
public:
static MY_data_process_factory* get_instance();
static MY_data_process_base* create_processer(DATA_TYPE data_type, DATA_DIRECTION data_dir);
static void detory();

private:
static MY_data_process_factory* m_this;

// 构造析构方法私有,只能用create_processer和detory来建立和释放资源
private:
MY_data_process_factory(void);
virtual ~MY_data_process_factory(void);

bool is_valid_type_and_dir(DATA_TYPE data_type, DATA_DIRECTION data_dir);
uint16_t calc_map_key(DATA_TYPE data_type, DATA_DIRECTION data_dir);

// 正常类方法和成员
private:
MY_data_process_base* create_processer_by_DataTypeA(DATA_DIRECTION data_dir);
MY_data_process_base* create_processer_by_DataTypeB(DATA_DIRECTION data_dir);

private:
std::map<uint32_t, MY_data_process_base*> m_map_processer;
};

#endif // #define ___TEST_DATA_FACTORY_MY_DATA_PROCESS_FACTORY_H__


// @file \testcase\test_data_factory\MY_data_process_factory.cpp

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

#include "MY_data_process_factory.h"

#include "MY_data_process_TYPE_A_DIR_UP.h"
#include "MY_data_process_TYPE_A_DIR_DOWN.h"
#include "MY_data_process_TYPE_A_DIR_LEFT.h"
#include "MY_data_process_TYPE_A_DIR_RIGHT.h"

#include "MY_data_process_TYPE_B_DIR_UP.h"
#include "MY_data_process_TYPE_B_DIR_DOWN.h"
#include "MY_data_process_TYPE_B_DIR_LEFT.h"
#include "MY_data_process_TYPE_B_DIR_RIGHT.h"

MY_data_process_factory* MY_data_process_factory::m_this = NULL;

MY_data_process_factory::MY_data_process_factory(void)
{
}

MY_data_process_factory::~MY_data_process_factory(void)
{
std::map<uint32_t, MY_data_process_base*>::iterator it;
MY_data_process_base* p_processer = NULL;

for (it = m_map_processer.begin(); it != m_map_processer.end(); it++) {
p_processer = it->second;
if (NULL != p_processer) {
delete [] p_processer;
p_processer = NULL;
}
}

m_map_processer.clear();
}

MY_data_process_factory* MY_data_process_factory::get_instance()
{
if (NULL == MY_data_process_factory::m_this) {
MY_data_process_factory::m_this = new MY_data_process_factory();
}

return MY_data_process_factory::m_this;
}

void MY_data_process_factory::detory()
{
if (NULL != MY_data_process_factory::m_this) {
delete MY_data_process_factory::m_this;
MY_data_process_factory::m_this = NULL;
}
}

bool MY_data_process_factory::is_valid_type_and_dir(DATA_TYPE data_type, DATA_DIRECTION data_dir)
{
bool b_rc = false;

do {
if ((DATA_TYPE_UNKNOWN == data_type)
|| (DATA_DIRECTION_UNKNOWN == data_dir)) {
break;
}

b_rc = true;
} while (0);

return b_rc;
}

uint16_t MY_data_process_factory::calc_map_key(DATA_TYPE data_type, DATA_DIRECTION data_dir)
{
uint16_t w_rc = 0;

w_rc = data_type;
w_rc <<= 8;
w_rc &= 0xff00;

w_rc |= data_dir;

return w_rc;
}

MY_data_process_base* MY_data_process_factory::create_processer(DATA_TYPE data_type, DATA_DIRECTION data_dir)
{
uint16_t map_key = 0;
MY_data_process_factory* p_factory = NULL;
MY_data_process_base* process_er = NULL;
std::map<uint32_t, MY_data_process_base*>::iterator it;

do {
p_factory = get_instance();
if (NULL == p_factory) {
break;
}

if (!p_factory->is_valid_type_and_dir(data_type, data_dir)) {
break;
}

map_key = p_factory->calc_map_key(data_type, data_dir);

it = p_factory->m_map_processer.find(map_key);
if (it != p_factory->m_map_processer.end()) {
process_er = it->second;
} else {
switch (data_type) {
case DATA_TYPE_A:
process_er = p_factory->create_processer_by_DataTypeA(data_dir);
break;

case DATA_TYPE_B:
process_er = p_factory->create_processer_by_DataTypeB(data_dir);
break;

default:
break;
}

if (NULL != process_er) {
p_factory->m_map_processer.insert(std::make_pair(map_key, process_er));
}
}
} while (0);

return process_er;
}

MY_data_process_base* MY_data_process_factory::create_processer_by_DataTypeA(DATA_DIRECTION data_dir)
{
MY_data_process_base* process_er = NULL;

switch (data_dir) {
case DATA_DIRECTION_UP:
process_er = new MY_data_process_TYPE_A_DIR_UP();
break;

case DATA_DIRECTION_DOWN:
process_er = new MY_data_process_TYPE_A_DIR_DOWN();
break;

case DATA_DIRECTION_LEFT:
process_er = new MY_data_process_TYPE_A_DIR_LEFT();
break;

case DATA_DIRECTION_RIGHT:
process_er = new MY_data_process_TYPE_A_DIR_RIGHT();
break;

default:
break;
}

return process_er;
}

MY_data_process_base* MY_data_process_factory::create_processer_by_DataTypeB(DATA_DIRECTION data_dir)
{
MY_data_process_base* process_er = NULL;

switch (data_dir) {
case DATA_DIRECTION_UP:
process_er = new MY_data_process_TYPE_B_DIR_UP();
break;

case DATA_DIRECTION_DOWN:
process_er = new MY_data_process_TYPE_B_DIR_DOWN();
break;

case DATA_DIRECTION_LEFT:
process_er = new MY_data_process_TYPE_B_DIR_LEFT();
break;

case DATA_DIRECTION_RIGHT:
process_er = new MY_data_process_TYPE_B_DIR_RIGHT();
break;

default:
break;
}

return process_er;
}


// @file : \test_data_factory\MY_data_process_base.h
// @brief : ...
#ifndef ___TEST_DATA_FACTORY_MY_DATA_PROCESS_BASE_H__
#define ___TEST_DATA_FACTORY_MY_DATA_PROCESS_BASE_H__

#define MY_DATA_PROCESS_OK 0
#define MY_DATA_PROCESS_ERR (unsigned int)(-1)

class MY_data_process_base
{
public:
MY_data_process_base(void);
virtual ~MY_data_process_base(void);

// 处理数据,返回错误码
// 返回 MY_DATA_PROCESS_OK = 成功,其他值失败
virtual unsigned int process(const unsigned char* puc_data, int i_data_len) = 0;
};

#endif // #define ___TEST_DATA_FACTORY_MY_DATA_PROCESS_BASE_H__


// @file \testcase\test_data_factory\MY_data_process_base.cpp

#include "MY_data_process_base.h"

MY_data_process_base::MY_data_process_base(void)
{
}

MY_data_process_base::~MY_data_process_base(void)
{
}


// @file : \testcase\test_data_factory\MY_data_process_TYPE_A_DIR_RIGHT.h
// @brief : ...
#ifndef ___TESTCASE_TEST_DATA_FACTORY_MY_DATA_PROCESS_TYPE_A_DIR_RIGHT_H__
#define ___TESTCASE_TEST_DATA_FACTORY_MY_DATA_PROCESS_TYPE_A_DIR_RIGHT_H__

#include "my_data_process_base.h"

class MY_data_process_TYPE_A_DIR_RIGHT :
public MY_data_process_base
{
public:
MY_data_process_TYPE_A_DIR_RIGHT(void);
virtual ~MY_data_process_TYPE_A_DIR_RIGHT(void);

virtual unsigned int process(const unsigned char* puc_data, int i_data_len);
};

#endif // #define ___TESTCASE_TEST_DATA_FACTORY_MY_DATA_PROCESS_TYPE_A_DIR_RIGHT_H__


// @file \testcase\test_data_factory\MY_data_process_TYPE_A_DIR_RIGHT.cpp

#include "MY_data_process_TYPE_A_DIR_RIGHT.h"

MY_data_process_TYPE_A_DIR_RIGHT::MY_data_process_TYPE_A_DIR_RIGHT(void)
{
}

MY_data_process_TYPE_A_DIR_RIGHT::~MY_data_process_TYPE_A_DIR_RIGHT(void)
{
}

unsigned int MY_data_process_TYPE_A_DIR_RIGHT::process(const unsigned char* puc_data, int i_data_len)
{
return MY_DATA_PROCESS_ERR;
}


// @file : \testcase\test_data_factory\MY_data_process_TYPE_B_DIR_DOWN.h
// @brief : ...
#ifndef ___TESTCASE_TEST_DATA_FACTORY_MY_DATA_PROCESS_TYPE_B_DIR_DOWN_H__
#define ___TESTCASE_TEST_DATA_FACTORY_MY_DATA_PROCESS_TYPE_B_DIR_DOWN_H__

#include "my_data_process_base.h"

class MY_data_process_TYPE_B_DIR_DOWN :
public MY_data_process_base
{
public:
MY_data_process_TYPE_B_DIR_DOWN(void);
virtual ~MY_data_process_TYPE_B_DIR_DOWN(void);

virtual unsigned int process(const unsigned char* puc_data, int i_data_len);
};

#endif // #define ___TESTCASE_TEST_DATA_FACTORY_MY_DATA_PROCESS_TYPE_B_DIR_DOWN_H__


// @file \testcase\test_data_factory\MY_data_process_TYPE_B_DIR_DOWN.cpp

#include "MY_data_process_TYPE_B_DIR_DOWN.h"

MY_data_process_TYPE_B_DIR_DOWN::MY_data_process_TYPE_B_DIR_DOWN(void)
{
}

MY_data_process_TYPE_B_DIR_DOWN::~MY_data_process_TYPE_B_DIR_DOWN(void)
{
}

unsigned int MY_data_process_TYPE_B_DIR_DOWN::process(const unsigned char* puc_data, int i_data_len)
{
return MY_DATA_PROCESS_ERR;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: