1、数据驱动
考虑这样一个场景:
我们同时需要从buffer1、buffer2、buffer3中分别取出数据,并应用任意的逻辑计算得到一个Result,我们要怎么做?
①不经过大脑的话,应该是这样
{
if(is buffer1)
access(buffer1)
if(is_buffer2)
access(buffer2)
...
}
这样的逻辑的确可以解决当前问题,然而某一天早上突然被告知需要buffer4、buffer5这样的东西,就只能继续和if else较劲。
②再来看下面一种解法
container{buffer1,buffer2,buffer3,...,buffern};
foreach(buffer in container){
access(buffer)
...
}
对比之下应该看出来第1种解法的缺陷,它的根本问题就在于试图用逻辑去表达数据(把数据变成了逻辑负担),第二中解法则比较灵活,也叫数据驱动编程。
2、元数据(MetaData)
再考虑:假如每个buffer拥有数据类型是不同的会怎样?
...
if(buffer1)
visitbuffer1(buffer1)
if(buffer2)
visitbuffer2(buffer)
...
if else 用起来太方便了 - -!(这种做法不用说也知道很恶心了)。
考虑我们需要的是什么,其实只是从某个buffer中(怎么)拿到(怎样)的数据。
我们可以设计一种统一的数据类型来达到上面的目的:
MetaData
{
int : slot //该数据所在的buffer位于container位置
int : stripe //访问幅度
int : format //数据格式
int : index //数据索引
}
然后我们可以做一个子例程来存取Metadata
output VisitMetaData(MetaData data)
{
buffer = container[data.slot];
data = buffer[data.strip*data.index];
switch(format)
{
...
}
return output(data);
}
这样就可以不用关心有多少数据类型,甚至不用知道buffer和container的存在,本质是在做抽象,抽象的好处就不言而喻了,我更喜欢把它叫做“数据抽象”哈哈。
关于数据组织方面可以参考《信息组织》这本书。