- 解耦代码和数据的重要性
- 手段
- 更复杂的情形
- 终极大法
- 一个例子
- 好处:
- 分开维护数据和代码(可维护性)
- 增加新的错误码,不需要修改代码(可维护性)
- 简化代码结构(代码质量)
- 提高执行效率(代码质量)
- 坏处
- 不太直观,降低可读性
结论:好代码是多次重构出来的!
注:工程师-发现问题,解决问题。设计东西。
手段- 使用数组、枚举、宏定义等手段抽离、维护数据。(也可以索引值用枚举,字符串常量数据采用数组维护,数据也再次进行一次拆分)
- 为避免手误,或者程序、数据分离造成的两处更改不一致问题,使用编译器断言避免出现未有效维护的情形。
注:通常是更改数据,但是代码也需要更改,但是没有两者不对应,为了能保证两者对应采取的手段。
更复杂的情形- 有如下格式的消息数据包
type:request target:session/0 operation:create_plain_window requestId:d56464ed464566d655s56544465dd644f dataType:ejson dataLen:{ workspace: 3456789, name: "_current", title: "Hello, world!", class: "normal", }
- 希望解析为如下的数据结构
typedef enum{
PCRDR_MSG_TYPE_REQUEST = 0,
PCRDR_MSG_TYPE_RESPONSE,
PCRDR_MSG_TYPE_EVENT,
} pcrdr_msg_type;
typedef emum{
PCRDR_MSG_TARGET_SESSION = 0,
PCRDR_MSG_TARGET_WINDOW,
PCRDR_MSG_TARGET_TAB,
PCRDR_MSG_TARGET_DOM,
}pcrde_msg_target;
typedef enum{
PCRDR_MSG_ELEMENT_TYPE_VOID = 0,
PCRDR_MSG_ELEMENT_TYPE_CSS,
PCRDR_MSG_ELEMENT_TYPE_XPATH,
PCRDR_MSG_ELEMENT_TYPE_HANDLE,
}pcrdr_msg_element_type;
pcrdr_msg_type pcrdr_message_get_type(const pcrdr_msg *msg);
typedef enum{
PCRDR_MSG_DATA_TYPE_VOID = 0,
PCRDR_MSG_DATA_TYPE_EJSON,
PCRDR_MSG_DATA_TYPE_TEXT,
}pcrdr_msg_data_type;
struct _pcrdr_msg{
pcrdr_msg_type type;
pcrde_msg_target target;
pcrdr_msg_element_type elementType;
pcrdr_msg_data_type dataType;
unsigned int retCode;
uintptr_t targetValue;
char * operation;
char * element;
char * property;
char * event;
char * requestId;
size_t dataLen;
char * data;
};
- 通过键值,返回特定数据类型
- 通过键值,索引函数指针
static size_t max = sizeof(key_ops)/sizeof(key_ops[0]) -1;
size_t low = 0,high = max, mid;
while(low <= high)
{
int cmp;
mid = (low +high) / 2;
cmp = strcasecmp(key, key_ops[mid].key)
if (cmp == 0)
{
goto found;
}
else{
if (cmp < 0)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
}
return NULL;
found:
return key_ops[mid].op;
}
终极大法
用脚本生成代码:
- 让程序处理大量的重复性编码工作,避免手工编写引入错误
- 处理字符串时,字符串较多时,二分查找性能不高,可以用哈希表;
- 用脚本,可以找到一个相对均衡的哈希算法
- 依赖构建系统自动维护代码的重新生成
- 如何快速获取CSS属性(如width、height、color)的内部属性信息?
- 我们准备一个描述文件
- 然后用python脚本处理这个文件并自动生成代码
background-attachment values: scroll fixed inherit initial: scroll inherited: no background_color values:inherit initial: transparent inherited: no ......
""" Make CSS property value macros: 1. Read 'propertylist.txt'file 2. Generate CSS property identifier list(enum) 3. Generate CSS property value keyword list(enum) 4. Generate CSS property value macros 5. Write code to 'csspropertyvalue.inc','cssdeclared.inc',and'cssinitial.cc'files """
typedef enum _CssPropertyIds {
// background-attachment
PID_BACKGROUND_ATTACHMENT,
// background-color
PID_BACKGROUND_COLOR
......
}
typedef enum _CssPropertyValueTypes {
PVT_NONE = 0,
PVT_KEYWORD,
......
}
bool setBackgroundIamge(Uint32 value ,HTInt data){
return Css::setProperty (PID_BACKGROUND_IMAGE, value, data);
}
......
#include "css/cssinitial.h"
namespace hfcl {
CssInitial* CssInitial::s_singleton = NULL;
CssInitial::CssInitial()
{
memset(&m_data, 0 ,sizeof(m_data));
memset(&m_arraysize, 0, sizeof(m_arraysize));
//Initial value
m_values[PID_BACKGROUND_ATTACHMENT] = MAKE_CSS_PPT_INITIAL_VALUE(CSS_PPT_VALUE_MARK_)
}
....
}



