Reputation: 2966
I ran into some design issues in Scala that relate to auxiliary constructors having to immediately call the primary (or other auxiliary)
I think the following example demonstrates the concept
class Matrix(args: AbstractRowColumn*) { ... }
class Column(elem: Double*) extends AbstractRowColumn { ... }
class Row(elem: Double*) extends AbstractRowColumn { ... }
Here, I think that a Matrix should be constructed by either Rows or Columns. However, this results in issues because each requires a different set of logic that first must be done before calling a constructor. (e.i Column must have it's elements processed in a different order than Row before creating the final Matrix)
How do I get around this? Better design?
Upvotes: 0
Views: 145
Reputation: 3547
The whole point of Scala's primary constructor is that each class should have a single consistent internal representation, attaching behavior to an (ideally immutable) set of data specified as the class parameters.
Consider making Matrix
abstract over some basic operations and then making two implementations:
abstract class Matrix {
def get(r: Int, c: Int): Double
def numRows: Int
def numCols: Int
}
case class RowMatrix(rows: Array[Row]) extends Matrix {
def get(r: Int, c: Int): Double = rows(r)(c)
def numRows: Int = rows.length
def numCols: Int = rows(0).length
}
case class ColumnMatrix(cols: Array[Column]) extends Matrix {
def get(r: Int, c: Int): Double = cols(c)(r)
def numRows: Int = cols(0).length
def numCols: Int = cols.length
}
Upvotes: 3
Reputation: 272207
each requires a different set of logic that first must be done before calling a constructor.
Sounds like you need a builder of some fashion e.g.
val matrix = MatrixBuilder.withRows(....).build
Upvotes: 1