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

标签 scala generics design-patterns .obj wavefront

我遇到以下问题(在 Scala 中)...

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

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

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

  • A 型:Array[Float] , Array[Int]
  • B 型:Array[Float] , Array[Float] , Array[Int]
  • C 型:Array[Float] , Array[Float] , Array[Int]
  • D 型:Array[Float] , Array[Float] , Array[Float] , Array[Int]

我发现了两种方法:

<强>1。方法:

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

  • A 型:case class TypeA(vertices: Array[Float], index: Array[Float])
  • B 型:case class TypeB(vertices: Array[Float], textures: Array[Float], index: Array[Float])
  • C 型:case class TypeC(vertices: Array[Float], normals: Array[Float], index: Array[Float])
  • D 型:case class TypeD(vertices: Array[Float], textures: Array[Float], normals: Array[Float], index: Array[Float])

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

<强>2。方法 我创建了类似 super 模型的东西:

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,也许为所有这些创建一个特征,然后您将看到是否可以将它们分组为类型以及是否值得。

关于scala - 如何设计不同类型的(几乎)相同的(在 Scala 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59027520/

相关文章:

scala - 无法使用 Spark 结构化流覆盖默认值 "spark.sql.shuffle.partitions"

java - 如何概括一种在 Java 中对 Map 条目进行排序的方法?

java - 根据对象类型调用方法

javascript - 简单的添加/删除组件模式

c++ - 这个 C++ 模式的名称及其背后的原因是什么?

scala - 如何将特征表达式转换为单个抽象方法

scala - 在 scala 中使用可变长度参数

scala - Spark ML 将预测标签转换为字符串,无需训练 DataFrame

java - 在这个 Java 类层次结构中,如何使用泛型来避免类型转换?

java - Java 泛型中类型删除规则的混淆