编码与建模成心态

但是,具体而言,为什么我要开始做一个像劳动密集型的项目一样(对于许多人来说,本质上是困难的,并且超出他们的舒适范围),而当我可以简单地开始编写代码并以后再担心状态和责任分配?

也许下面的实际示例可以让我对为什么选择这种方法有所了解,还可以说明在何处以及为何仍然需要手动编码。

产品负责人向我提出他需要解决的问题。 在公司的数据存储中,有成千上万的高分辨率图像。 它们被保存在各种类型的媒体上,无论当时是什么。

由于许多此类介质的读取器现在不可用,甚至很难找到或找不到某些零件,因此他需要在大型NAS系统上创建所有这些映像的数据仓库,同时使读取器仍在运行。 到目前为止,还不错,还没有软件问题,也许他只是在大声思考?

但是,没有任何一件事情容易解决。

在传输这些图像时,他想创建一个特定于图像的数据存储,而这正是我的问题。 这些图像都是TIFF格式,但是正如我已经知道的,“ TIFF格式”几乎可以表示任何东西,因为“标记图像文件格式”中的标签决定了随后的图像数据的实际格式:可以是CMYK或RGB数据; 它可以交错或不交错; 等等

幸运的是,该公司提供了一些库,这些库在可以从TIFF图像中提取数据方面超越了ImageMagick,其中包括可以创建这些文件的较小版本的库,因为它们大多数是在Crosfield或Highwater扫描仪上创建的,并且结果为2540 DPI分辨率。

就图像的实际格式而言,有些是标准的RGB Photoshop类型的TIFF,但大多数起源于使用CMYK隔行TIFF的Scitex机器,或使用CMYK非隔行TIFF的Quantel Graphic Paintbox。

从最初的交谈中可以收集到的信息,我有以下基本要求:

•图像可浏览的数据存储,我认为它可以实现为某种键/值映射数据存储

•图像必须可由可从原始图像提取或由人类作为标签输入的任何数据搜索

•还必须通过某种可能尚未编写算法的图像识别系统来搜索图像

•图像必须可以通过某种编辑器进行编辑,可以通过丰富的GUI应用程序或通过Web应用程序进行访问

您可能已经注意到,很多困难的编码已经在库中完成,我只需要插入它们即可。其他正在编写中,但是它们是其他人的问题。 我的问题主要是创建和维护海量数据集的状态(很可能是想出像样的图像识别算法)。

当然,鉴于分析是以SCSI-III速度(每秒仅数百MB)对流数据进行的,因此他们将需要给我一些不错的部署硬件。

从我上面写的内容看来,这对于基于建模的解决方案来说似乎是一个完美的问题。 当然是因为我选择了它。

现实生活永远不会如此巧妙地进行,例如,在现实生活中,这不是我会特别选择的项目。

现在,我应该做出一些关键决定:

  • 鉴于我可能必须在成品中使用任何数据存储库,甚至可能在多个不同的存储库中使用数据存储库,我应该使用哪个数据存储库作为测试平台?
  • 我应该用什么语言写?
  • 我应该在什么环境中开发?

尽管大多数决策已经做出,但是由于公司拥有标准数据存储区,因此取决于所需的类型以及标准语言和环境。 在这种情况下,我们将说数据存储为MongoDB,语言为Java。 开发人员有时可以酌情决定环境,但是在此示例中,我们可以使用公司的首选环境Eclipse

碰巧的是,Eclipse具有强大的建模环境-EMF,即Eclipse建模工具。 EMF(以及诸如图形建模工具和扩展编辑工具的扩展)通过创建从EObject开始的并行对象层次结构,提供了比Java更适合于建模的语言(例如Smalltalk)所固有的许多功能,例如Smalltalk。注意熟练的建模技术所必需的反射率。

因此,首先,我将创建一个简单的EMF模型(或ECore模型),其中包含我需要为每个图像捕获的基本数据。 除TIFF标头中的文本数据外,我还需要两个低分辨率图像(缩略图和查看器尺寸的图像),以及对原始位置的引用。 由于我不是在一家完全是偶然的情况下拥有无数图像的公司中工作,所以我还认为我需要导出图像的矢量表示,以便识别和匹配算法可以对拓扑图像匹配进行拓扑处理。

我有几年前写的代码来生成TIFF位图的EPS矢量版本,将其转换为输出SVG而不是EPS将非常容易。 我还需要为可添加到人类或由人类更改的可编辑标签创建字段。

一旦创建了该模型,就可以通过用Java生成该模型的代码,该模型的简单GUI编辑框架,测试用例和一个CDO模型来进行尝试,这对于以后的持久性和维护状态更改很有用。

通过插入各种库并编写一些粘合代码,我实际上可以开始引入真实的图像数据,并且现在将其存储在Eclipse内部管理的本地CDO存储库中。

鉴于我不知道TIFF标头中的所有潜在标签,我将使模型的这一部分成为动态的,其中模型字段是根据数据进行反射性确定的,然后用于存储,持久化和编辑这些字段,只要遇到新型的TIFF。

然后,我可以生成代码(通过称为Texo的EMF库)以将CDO模型持久存储到MongoDB(或任何其他JPA支持的数据存储)。

鉴于相当复杂的模型(包括每个图像的反向工程拓扑所需的所有元素)可能需要一周左右的时间来创建和测试。 我现在有一个满足初始要求的原始软件版本。

由于编辑器是在Eclipse RCP(富客户端平台)中创建的,因此我可以使用RCP远程处理(也称为RAP)来使编辑功能通过Web服务器提供给浏览器客户端。 稍后,当我优化完成的程序时,我可以用更具动态性的Web客户端替换RAP,并用QT替换RCP应用程序的顶层以获得更动态和更具吸引力的富客户端。

完整的价值体现在产品演示者看到其可以做什么之后,它开始更加清晰地看到其需要做什么。

可以将更详细(且不断变化)的需求快速实现为模型更改,并重新生成并自动测试模型,持久性和编辑的代码。

随着对UI的要求超越了简单的文本字段,通过EEF和GMF应用的更高级的控件也将被创建一次,并在基础模型发生更改时重新生成。 我可以通过简单的EMF转换创建数据的任意视图,并且在整个转换过程中维护对象结构的映射,从而允许转换后的数据视图更新原始图像。

最后,我可以生成JPA代码,以不仅在CDO中而且在Cassandra,Mongo,Hadoop或RDBMS中持久保存模型的每个版本,而无需额外的编码。

由于模型既包含数据又包含行为状态更改,包括指定后者的责任,因此,软件设计的两个最基本方面被捕获到模型中,并且可以快速进行检查,判断,纠正和优化。 我可以使用EMF Compare和EMF Diff / Merge对我的拓扑/地形模型进行全面比较,从而可以节省那些不得不编写匹配算法的糟糕草皮,这可能需要很多工作,甚至可能是理智的。

在此特定示例中,该软件的原始版本包括大约600,000行Java代码。 也许如果我手工编码它,它可能会下降四分之一,但仅此而已。 数据的任何新视图都需要大约100,000行代码,并且如果这些表示是经过手工编码的,则试图确保给定的表示可以成功进行修改和持久化几乎是不可能的,而更改图是生成的代码的固有部分始终如一地为我做到这一点。

唯一的困难是,系统的大部分,直到它完成并工作(甚至大部分都是动态部件),才存在于我所具有的想象力投影中。 这不仅需要具有想象力的能力,而且还要在个人的想象力中保持投射,直到充分实现模型以生成工作系统为止。 那可能很累。

但是,考虑到这之间的选择和手写数十万行(通常是死记硬背)代码的过程,通常是多次,所以我接受。

没有人说开发应该在各个方面都很容易。

这也有助于回答以下问题:为什么与诸如适当命名的“ Sublime Text”之类的文本编辑器相比,Eclipse使用了如此多的内存。 (根据黑格尔对Sublime的定义,恰当地命名为“所有母牛都黑了的夜晚”,也就是说,无法分辨或理解任何东西。)Pharo OSS Smalltalk环境的工具比Eclipse更好,但使用的资源却比Sublime Text少,证明它有点困难。

当然,将位图转换为矢量文件或精确的图像识别都不是可以从模型生成的代码,至少目前还不能,因为我们甚至没有关于地形和拓扑之间所有可能关联的理论。

因此,要做到这一点将涉及这些方面的详细实现。

在那些领域中,有必要进行手工编码,并将在可预见的将来使用这些编码。但是,即使在那些领域中,我也会倾向于信任那些根据关系来确定哪些事物是必要的,在什么地方进行思考的人,而不是那些思考并尝试过的人。使他们以某种方式联系起来以取得成果。