Scala技术来组织代码

时间:2014-12-25 01:49:17

标签: scala

我正在学习Scala。现在,我正在重新组织我的一个项目并需要帮助。

假设我的程序有两部分。第一部分的输出用作第二部分的输入。以下数据结构由第一部分创建: 两个数组,两个矩阵,一个双等。

程序的第二部分使用上述数据结构(并使用一些额外的文件),最后将输出写入一个/多个文件。

组织该计划的最佳方式是什么?如何将所有内容保存在内存中,但仍然将数据结构从第一部分“传递”到第二部分?我不想将第一部分的输出写入文件并再次读取它们。

谢谢和问候,

2 个答案:

答案 0 :(得分:1)

一种方法是在元组中传递信息:

object MyApp extends App {
  def part1 {
    // do lots of work, perhaps using 'args' off the command line
    (array1, array2, matrix1, matrix2, dbl, ...)
  }
  def part2(p1: (<types for all of those things>)) {
    // do more work
  }
  part2(part1)
}

当然,您可以创建一个案例类来保存信息; part1将创建case类的实例,part2将实例作为参数:

object MyApp extends App {
  case class Part1Result(array1: ..., array2: ..., ...)
  def part1 {
    // do lots of work, perhaps using 'args' off the command line
    Part1Result(array1, array2, matrix1, matrix2, dbl, ...)
  }
  def part2(result: Part1Result) {
    // do more work
  }
  part2(part1)
}

当然,part1可以使用多个参数显式调用part2。

或者你可以从globals中的part1中捕获结果:

object MyApp extends App {
  def part1 {
    // do lots of work, perhaps using 'args' off the command line
    (array1, array2, matrix1, matrix2, dbl, ...)
  }
  val (array1, array2, matrix1, matrix2, dbl, ...) = part1
  def part2 {
    // do more work, accessing the globals
  }
  part2
}

当然,如果您只想内联编写代码,那么defs没有理由:

object MyApp extends App {
  val (array1, array2, matrix1, matrix2, dbl, ...) = {
    // do lots of work, perhaps using 'args' off the command line
    (array1, array2, matrix1, matrix2, dbl, ...)
  }
  // do more work, accessing the globals
}

但我不建议使用全局变量来保存结果,因为访问全局变量会使第二部分的单元测试难以编写。

很可能这两个部分对应于其他地方定义的类,所以也许你想要的就像

object MyApp extends App {
  new Part2(new Part1(<args off the command line>).result)
}
class Part1 {
  ...
  def result = (array1, array2, ...)
}
class Part2(p1Result: (...)) {
}

其中Part1#result返回元组或案例类。

实际上,不是在result实例上调用Part1方法并返回结果对象,Part1对象本身可以拥有结果的访问器:

object MyApp extends App {
  new Part2(new Part1(<args off the command line>))
}
class Part1 {
  val array1 = ...
  val array2 = ...
  ...
}
class Part2(p1: Part1) {
  // lots of work, referencing p1.array1, etc.
}

如你所见,你有很多选择!

您肯定希望您的部件可以独立测试:您将测试给定的特定输入集,他们做正确的事情。出于这个原因,你想让第二部分直接调用第一部分,例如

def part2 = {
  val p1Results = part1  // oops, don't do this!
  ...
}

因为这意味着你可以用一组特定输入测试part2的唯一方法是弄清楚如何将part1转换为生成这些输入作为输出。这是一个无赖 - 你想要的是每个部分将其输入作为参数,以便在单元测试中你可以传递你想要的任何东西。如果第一部分返回一个简单的数据对象而第二部分将这样的对象作为参数,那么单元测试很容易。如果将Part1实例作为参数传递给Part2实例,您仍然可以进行单元测试,但是您必须根据Part1实现的特性来定义Part2的参数,以便您可以提供不同的实现在测试中。

创建一个易于测试的解决方案的最简单方法可能是让Part1生成一个案例类的实例,该案例类作为参数提供给Part2(前面提到的案例类解决方案)。

答案 1 :(得分:0)

这样做的最好方法是使用案例类。

object HeavyLifting 
{
  def part1 {
    // do the heavy lifting
    CaseClassExample(array1, array2, matrix1, matrix2, dbl, ...)
  }

  def part2 {
    val getData= part1    // here u r getting an object of case class

    getData.array1       // and this is how u can fetch individual array, matrix etc
    getData.matrix1
  }
}
case class CaseClasssExample(array:Array[Int], ..... )   // here u can define ur case class, what all kind of data u want to store in it.


//case classes will be helpful in mattern matching