在开发SCIFIO时,我们的护理任务之一就是格式兼容。SCIFIO彻底修改了Bio-Formats类结构,将每个阅读器分割为一组原子组件。虽然几乎所有的Bio-Formats API都可以用SCIFIO API表示,但即使没有直接的模拟方法调用,也有一些新的考虑因素(例如从阅读器中状态,添加或Nvi支持)将改变软件的工作方式。
我们对 SCIFIO 的第一次转换测试是loci.common组件。许多转换后的转换完全保留了它们的功能,但被迁移到新的(ome.scifio)包中。这强调了一个基本的兼容性问题:平台是软件合同的一部分。自然的类方案是创建委托者类,通过功能控制传递给现代类来继承继承 API。
不幸的是,有些问题需要解决。接口尤其是一个问题:如果您希望继承对象可以在现代方法签名中使用,您可以尝试扩展现代应答接口(我就是内在的)。但是,此时您将把自己锁定在API中。如果在现代界面中立即添加功能,由于继承,您会破坏继承层中的格式兼容性。体实现您通过每个方法定义中的变通方法来监听低级API在这些更改中,但是当您有一个方法,例如,采用继承类型,然后将其自己的功能委托给需要该类型的现代版本的方法时,您仍然会遇到键入问题(继承实际上已经为您解决了……正好,它只是有点遥不可及,搞笑地)。
为了这些问题,我们创建了一个 wrappers 接口和 Abstract 实现,前提是使用实体LegacyAdapter(即解决一类是 Legacy 并包装了 Modern,反亦之然),并且让每个支架都维护每个 Legacy 或 Modern 实例到其包装器的映射。
在它的模型中,没有继承,不必担心意外破坏未来开发的格式兼容性,并且不会锁定 API。包装器还允许一些优雅的逻辑:只要您有 Legacy 或 Modern 实例并且需要另一个实例时,您就检查它是否已经是 Wrapper 。如果是这样,打开,您一定会得到需要的类型。如果没有,就包起来!
因为我们再次想要实例维护和包装器之间的映射,所以创建一个静态§§2§§§实用程序非常有意义,该实用程序具有一个(通用参数化)方法,该方法采用适配器类并返回该适配器的静态维护实例。静态适配器意味着映射是静态可用的,一旦对象被包装,就永远不会被包装,并且您可以通过在软件中的任何使用位置实例与包装器来期望一致的。
我对这个实现唯一不喜欢的是Bio-Formats还没有使用SezPoz(当SCIFIO完全上线时它才会使用),因此必须通过实例化每个已知牙齿类的编码硬调用来填充映射。牙齿模式非常适合自动发现机制,一旦因此SCIFIO准备好向公众开放,它就成为我的愿景清单中的重中之重。
就目前情况而言,适配器仍然存在一个重大限制(据我同样):如果您扩展旧的 Bio-Formats 类(例如,使用 Kraken extends IRandomAccess 类),然后使用某种扩展类的实例 (destroyTheMonster(Kraken kraken)) 的创建方法,则您将必须自己的 Adapter,然后尝试将硬编码实例化到主代码库中的AdapterTools中。这可能是一个重大的改进,因此现在我建议选择继续继承类进行操作,或者将代码转换为使用 SCIFIO 包名称。(晚上是首选,您可以继续从 SCIFIO 获得任何改进)
将来,有了 SezPoz 支持,您仍然需要创建 Adapter,但通常将其注释为 Adapter,它会自动包含在静态 AdapterTools 类中,并且您的库将自动用作 Bio-Formats/SCIFIO 的插件。
~Mark Hiner