理论情况:
一万亿页文件存储在文本文件中(没有高级数据库)。每个foobar必须在其上执行一些业务逻辑。一组1万亿将不适合内存,因此数据层不能将一个大集返回到业务层。相反,它们一次被流到一个foobar中,并让业务逻辑一次在一个foobar上执行。完成后,流必须关闭。
为了关闭流,业务层必须关闭流(数据操作细节),从而违反了关注点的分离。
是否有可能在不违反层的情况下增量地处理数据?
发布于 2012-10-05 05:37:06
问得好。
这里有一个C#-ish代码,它可以让你两全其美。这里的诀窍是懒惰的评估(产量)。
// Lazy producer that will auto-close the file.
// The OS and the disk do the caching for you.
public static IEnumerable<FooBar> GetFoobars(string fileName, long maxNumber = 1000000000000)
{
using(File file = open(fileName)) // pseudocode
{
FooBar nextFooBar;
do
{
nextFoobar = new Foobar(file.ReadByte()); // or something like that.
yield return nextFoobar;
}
while(nextFooBar != null || /* reach max */); // pseudocode
}
}
// Consumer ... stupid example. Oh well ...
public static int Consume()
{
int result = (from foo in GetFoobars("foo.txt").AsParallel()
where foo.Depth % 10 == 0).Count();
return result;
}GetFoobars(...)函数知道要打开哪个文件,要读取多少个文件,以及如何关闭流。你只要按你需要的结果就行了。关注是分开的。什么地方出问题了?你很可能会把整件事做成一条线.也许不是,但很接近。
我建议大家看一下SICP的视频讲座。
发布于 2012-10-05 02:00:30
是否有可能在不违反层的情况下增量地处理数据?
是的,是这样的。你必须定义工作单位,这将解决你的困惑。我认为处理一组记录(100或1000取决于平均记录的处理时间)或一次记录将有更可靠和可管理的结果。
此外,我将确保数据操作过程(业务处理)在事务中,所有错误处理的记录和回滚以供调查。你可能总是有一些特殊的情况,必须加以考虑。
发布于 2012-10-05 03:46:28
定义一个抽象接口,它显示一个foobar (或任何所需的foobar集),由抽象的实现来确定foobar是如何获得和/或修改的。
当然,您需要围绕这个实际情况定义这个接口的元素。如果计算foobar的唯一方法是流过所有的万亿,那么在您的界面中不要包括“获取foobars的数量”。但是,除了"get“之外,您的界面可能还会包含一些元素,比如"start”、“to”和"abort“。
https://softwareengineering.stackexchange.com/questions/167518
复制相似问题