lundi 25 novembre 2019

How to design different kinds of (nearly) the same

I have the following problem (in Scala)...

I want to read wavefront files (.obj) and transform them to something I can work with later. The wavefront files I want to support are files with the following definitions for:

  • TypeA: vertices and faces
  • TypeB: vertices, texture and faces
  • TypeC: vertices, normals and faces
  • TypeD: vertices, textures, normals and faces

I will read them and create a Mesh (a model class for later use) of it with the following fields:

  • TypeA: Array[Float], Array[Int]
  • TypeB: Array[Float], Array[Float], Array[Int]
  • TypeC: Array[Float], Array[Float], Array[Int]
  • TypeD: Array[Float], Array[Float], Array[Float], Array[Int]

I discovered two approaches:

1. Approach:

each type gets it's own model class

  • 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])

With this approach I don't have to check if all fields are present. I can use them out of the box. The disadvantage is: I need to create a "build"-method for each type (something like: createTypeAFromFile(filename: String))

2. Approach I create something like a uber-model:

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

With this approach I only need one "build"-method, but the problem here, later I have to check if the fields I want to use are really present (for normals and textures)

Question:

Does anyone knows a better approach/design, for this kind of problem?

Aucun commentaire:

Enregistrer un commentaire