数据的格式选择,和同源数据。
如果我们正在设计一个游戏系统,其中两个重要的部分 Sprite & Game,Game 负责整体逻辑,为了刷新每个 Sprite 的状态(位置,速度,加速度),Game 向 Sprite 发送 tick message。
// examples 1
public class Game {
private long lastTime;
private List<Sprite> spriteList;
public void start (); // lost code
public void run () {
long currTime = System.currentTime();
long tick = currTime - lastTime;
for (Sprite s : spriteList) {
s.tick(tick);
}
lastTime = currTime;
paint();
}
public void paint();
public void finish (); // lost code
};
public class Sprite {
public void tick (long t); // lost code
};
Sprite 接受的消息 tick 的参数可以是 current time(当前时间)或者是 difference time(间隔时间)。上面的例子采用了 difference time 的做法,这是一个设计上的选择,无论给出的是哪种参数都可以算出另一种参数,从游戏逻辑方面选择哪个都没有区别,但考虑到大多数的 Sprite 并不与绝对时间相关联,直接传递相对时间可以减少计算(and code)。或者说选择最利于处理的格式。
程序中经常有这种数据表达的问题,或者说同样的 Data 不同的 Representation,在分析阶段我们所关心的仅仅是 Data,而不是其 Representation。当然有时候为了说明问题会在设计中引入一个具体的 Representation,但这仅仅是临时性质的。在设计 Sprite 时我们所关心的仅仅是其“责任”、“接口”,Sprite 接受 tick message,The tick message 以时间为参数(not care about absolute or relative)。
在设计中需要将数据的格式确定下来,这时只要选择最利于处理的格式(而不是最利于产生的格式)。但是在具体实现中可能发现在某些条件下所选择的格式不适合,需要转换,如下中的 IntegerProgressPrint :
// example 2
public interface ProgressMonitor {
void updateProgress (float f);
};
public class IntegerProgressPrint implements ProgressMonitor {
void updateProgress (float f) {
System.out.println((int) (f * MAX_VALUE));
}
};
void run () {
int m;
for (m=0; m<MAX_VALUE; m+=processed()) {
progress.updateProgress((float) m / MAX_VALUE));
}
};
引起我们思考的是在某些时候,特别是以浮点数作为消息参数时候,有可能在参数转换过程中出现误差,为了避免这种情况出现,有必要同时传递同一个数据的多种Representation,例如:
// example 3, recode example 2
public interface ProgessMonitor {
void updateProgess (ProgressParam p);
};
public class ProgressParam {
public final int curValue;
public final int maxValue;
public final float procentage;
};
public class IntegerProgressPrint implements ProgressMonitor {
void updateProgress (ProgressParam p) {
System.out.println(p.curValue);
}
};
public class PercentProgressPrint implements ProgressMonitor {
void updateProgress (ProgressParam p) {
System.out.println(p.procentage);
}
};
我们称之为:同源数据。
结论:
1. 在设计过程中应该将精力集中在对象的责任上,不需要关心具体的数据表现形式。可使用常用/简单格式临时替代。
2. 在实现过程中如有必要使用同源数据。
如果我们正在设计一个游戏系统,其中两个重要的部分 Sprite & Game,Game 负责整体逻辑,为了刷新每个 Sprite 的状态(位置,速度,加速度),Game 向 Sprite 发送 tick message。
// examples 1
public class Game {
private long lastTime;
private List<Sprite> spriteList;
public void start (); // lost code
public void run () {
long currTime = System.currentTime();
long tick = currTime - lastTime;
for (Sprite s : spriteList) {
s.tick(tick);
}
lastTime = currTime;
paint();
}
public void paint();
public void finish (); // lost code
};
public class Sprite {
public void tick (long t); // lost code
};
Sprite 接受的消息 tick 的参数可以是 current time(当前时间)或者是 difference time(间隔时间)。上面的例子采用了 difference time 的做法,这是一个设计上的选择,无论给出的是哪种参数都可以算出另一种参数,从游戏逻辑方面选择哪个都没有区别,但考虑到大多数的 Sprite 并不与绝对时间相关联,直接传递相对时间可以减少计算(and code)。或者说选择最利于处理的格式。
程序中经常有这种数据表达的问题,或者说同样的 Data 不同的 Representation,在分析阶段我们所关心的仅仅是 Data,而不是其 Representation。当然有时候为了说明问题会在设计中引入一个具体的 Representation,但这仅仅是临时性质的。在设计 Sprite 时我们所关心的仅仅是其“责任”、“接口”,Sprite 接受 tick message,The tick message 以时间为参数(not care about absolute or relative)。
在设计中需要将数据的格式确定下来,这时只要选择最利于处理的格式(而不是最利于产生的格式)。但是在具体实现中可能发现在某些条件下所选择的格式不适合,需要转换,如下中的 IntegerProgressPrint :
// example 2
public interface ProgressMonitor {
void updateProgress (float f);
};
public class IntegerProgressPrint implements ProgressMonitor {
void updateProgress (float f) {
System.out.println((int) (f * MAX_VALUE));
}
};
void run () {
int m;
for (m=0; m<MAX_VALUE; m+=processed()) {
progress.updateProgress((float) m / MAX_VALUE));
}
};
引起我们思考的是在某些时候,特别是以浮点数作为消息参数时候,有可能在参数转换过程中出现误差,为了避免这种情况出现,有必要同时传递同一个数据的多种Representation,例如:
// example 3, recode example 2
public interface ProgessMonitor {
void updateProgess (ProgressParam p);
};
public class ProgressParam {
public final int curValue;
public final int maxValue;
public final float procentage;
};
public class IntegerProgressPrint implements ProgressMonitor {
void updateProgress (ProgressParam p) {
System.out.println(p.curValue);
}
};
public class PercentProgressPrint implements ProgressMonitor {
void updateProgress (ProgressParam p) {
System.out.println(p.procentage);
}
};
我们称之为:同源数据。
结论:
1. 在设计过程中应该将精力集中在对象的责任上,不需要关心具体的数据表现形式。可使用常用/简单格式临时替代。
2. 在实现过程中如有必要使用同源数据。