2014-12-25 59 views
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) 
} 

或者当然,你可以创建一个案例类来保存信息;第一部分将创建案例类和第2部分的实例,将采取一个实例作为参数:

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) 
} 

当然第一部分的或者可能明确要求第2部分与多个参数。

或者你可以捕获从第一部分的结果在全局:

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! 
    ... 
} 

,因为这将意味着你可以用一组特定的输入测试第2部分的唯一途径是找出如何让第一部分以产生这些输入输出口。这是一个无赖 - 你想要的是每个部分都将其输入作为参数,这样在单元测试中,你可以传递任何你想要的东西。如果第一部分返回一个简单的数据对象,第二部分将这个对象作为参数,那么单元测试很容易。如果将Part1实例作为参数传递给Part2实例,则仍然可以执行单元测试,但是您必须根据Part1实现的特性定义Part2参数,以便在测试中提供不同的实现。

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

+0

非常感谢,AmigoNico。请告诉我一些事情:是否也可以创建一个简单的类/对象来保存信息,还是Scala中禁止的信息? –

+0

当然,这是可能的。我添加了更多方法来实现它的示例。 – AmigoNico

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