创建子类只是为了在不同的子类之间进行转换

时间:2013-10-07 13:39:06

标签: java subclass base

我在找到刚刚加入的新公司的代码库之前发现了一些我从未想过的东西。基本上会发生这种情况:我们有一个基类,它代表一个带有几种抽象方法的Image,可以在不同的图像类型之间进行转换。不同的图像类型是基本Image类的子类。子类负责在不同的图像之间进行转换,这些图像都是派生类。

我的问题是这应该是一个好的设计吗?如果不是我们可以有什么替代品?

非常感谢。

2 个答案:

答案 0 :(得分:1)

如果我设计了场景,那么我会做以下事情......(N.B我不是一个非常优秀的设计师,只是分享我的概念)

  1. 使用抽象方法的基类图像,它只代表行为,而不是任何要转换的行为
  2. 实现那些定义行为的抽象类的子类
  3. 其他实用程序类,它具有在不同图像之间进行转换的方法。

答案 1 :(得分:1)

这不是最优雅的结构,但它可以工作 - 只要你只处理几种图像类型。将转换转换为公共基类的通用功能将更加优雅,并且可扩展到其他图像类型。缺点是引入了变化,并进行了一些自己的设计权衡。

关键的架构问题是:

  1. 哪里?您在哪里提供有关如何将X型转换为Y型的知识? X型内?里面的Y型?在一个共同的祖先里面?或者在一些单独的转换设施内?
  2. 如何? X应该知道如何直接导出到Y?或者Y应该知道如何从X导入?或者X应该导出为通用/通用格式,然后Y知道如何从中导入?
  3. 您可以在野外找到这些选项中的每一个。

    您当前的设计在每个图像类中都有转换,它反映了许多语言中相当基本的数据类型/类;他们每个人都希望能够将自己序列化,表示或转换为其他几种格式(例如,字符串,像pickle这样的线上格式等)。但是,如果有多种类型,则从-X到Y转换器写入quickly grow unmanageable。你将需要n(n-1)个转换方法 - “不是没有人有时间!”

    另一方面,像netpbmpandoc这样的全部转换和操作套件通常使用通用的中间表示。我所知道的最接近的模拟,像Python's PIL/Pillow这样的成像库,通常会定义一个通用基类(例如Image),它扮演通用格式/数据模型的角色,即使它们不是有自己的磁盘格式。

    抽象总是不完美的。当你刚刚处理X或Y时,继承是花花公子。但是当你需要处理类型X的错综复杂并同时输入Y 时,没有完美的答案。分解其他课程无济于事;也不会多重继承。

    范式和可能最好的整体答案是将转换转移到基类。但这并非没有自己的权衡。然后,基类必须知道并适应所有可能子类的转换。因此,即使您正在转换没有Alpha通道,CLUT,Z缓冲区,伽马校正表,HDR校准信息和其他数据/元数据的格式,基类方法和数据结构也必须了解和处理如果他们的子类的任何具有这些东西,那么这些东西。推动转换向上堆栈还可以导致基类和子类(在设计和运行时)之间的乒乓对话,因为基本方法试图询问子类或将任务委托给子类。但是,这些关于住房转换上升的担忧是二阶问题。它们并不太令人烦恼 - 除非你真的遇到它们。

    所以网络建议是:对于一些图像类型,转换可以合理地存在于每个图像类中。如果您已经拥有“手中的鸟”,那么尤其如此 - 已经采用这种方法的经过测试的代码。但是,如果要“清理”设计,将导入/导出/转换转移到基类会更加优雅,并且可以扩展到其他图像类型。 (在开始游行之前,请确保您对现有实现进行了良好的单元测试,以便您可以轻松获得第二代代码。)