繁体   English   中英

如何设计不同种类的(几乎)相同的(在 Scala 中)

[英]How to design different kinds of (nearly) the same (in Scala)

我有以下问题(在 Scala 中)...

我想读取波前文件 (.obj) 并将它们转换为我以后可以使用的文件。 我想要支持的波前文件是具有以下定义的文件:

  • TypeA:顶点和面
  • TypeB:顶点、纹理和面
  • TypeC:顶点、法线和面
  • TypeD:顶点、纹理、法线和面

我将阅读它们并使用以下字段创建一个网格(供以后使用的模型类):

  • 类型A: Array[Float]Array[Int]
  • 类型B: Array[Float]Array[Float]Array[Int]
  • TypeC: Array[Float] , Array[Float] , Array[Int]
  • TypeD: Array[Float] , Array[Float] , Array[Float] , Array[Int]

我发现了两种方法:

一、方法:

每种类型都有自己的模型类

  • TypeA: case class TypeA(vertices: Array[Float], index: Array[Float])
  • TypeB: case class TypeB(vertices: Array[Float], textures: Array[Float], index: Array[Float])
  • TypeC: case class TypeC(vertices: Array[Float], normals: Array[Float], index: Array[Float])
  • TypeD: case class TypeD(vertices: Array[Float], textures: Array[Float], normals: Array[Float], index: Array[Float])

使用这种方法,我不必检查所有字段是否都存在。 我可以立即使用它们。 缺点是:我需要为每种类型创建一个“构建”方法(例如: createTypeAFromFile(filename: String)

2. 方法我创建了一个类似超级模型的东西:

case class Mesh(vertices: Array[Float], textures: Option[Array[Float]], normals: Option[Array[Float]], index: Array[Float])

使用这种方法,我只需要一个“构建”方法,但是这里的问题,稍后我必须检查我想要使用的字段是否真的存在(对于法线和纹理)

题:

对于这种问题,有没有人知道更好的方法/设计?

如果您知道将对类型执行的操作通常会有所帮助,一篇很好的博客文章是: https : //www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction其中作者认为错误抽象比有一些重复更糟糕。

使用方法 1,也许为所有这些创建一个 trait,然后你会看到是否可以将它们分组到类型中,以及是否值得。

[感谢@simpadjo 的更新]

方法 3 是创建一个特征层次结构来表示不同的选项:

trait Faces {
  def vertices: Array[Float]
  def faces: Array[Float]
}
trait Textures extends Faces {
  def textures: Array[Float]
}
trait Normals extends Faces {
  def normals: Array[Float]
}
trait Obj3D extends Textures with Normals 

class A(
  val vertices: Array[Float],
  val faces: Array[Float]
) extends Faces

class B(
  val vertices: Array[Float],
  val textures: Array[Float],
  val faces: Array[Float]
) extends Textures

class C(
  val vertices: Array[Float],
  val normals: Array[Float],
  val faces: Array[Float]
) extends Normals

class D(
  val vertices: Array[Float],
  val textures: Array[Float],
  val normals: Array[Float],
  val faces: Array[Float]
) extends Obj3D

解析器可以返回Faces但如果附加字段可用,它会创建适当的子类。 然后您可以创建一个Faces Mesh ,但使用match来检测附加信息可用的情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM