2014-12-25 91 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