2014-01-16 149 views
1

我在設計模塊時遇到困難,任何人都可以幫助我嗎?哪種設計模式以及如何使用面向對象的這種設計模式設計

由於難以維護這種模塊,我也認爲這可以測試我設計模式使用的技巧。

要求

這基本上是一個農業項目(Web應用程序)。我需要設計一個模塊進行一些計算。

有不同的作物,如玉米,西紅柿,秋葵等。這些作物都有不同的性狀。

每個性狀都有一個像200-1000這樣的整數的測量尺度。現在讓我們說我已經種植了作物,並完成了測量。現在我想做一些測量。有些測量很簡單,有些很複雜。

示例

讓我們來看一個作物玉米的例子。我記錄了15個特徵的觀察結果。 (我們將使用trait1-trait15爲例,實際名稱可以像plt_ht,YLD等)

我記錄每個性狀5點意見:

trait1 trait2 trait3 trait5 trait6..... trait15 
01,02,03,04 01,02,03,04 01,02,03,04 

用戶登錄到系統並且選擇他作物併爲這些觀察輸入數據。我必須計算爲每個特徵輸入的數據的平均值或總和。問題的

複雜性/中心

到目前爲止,這很簡單,但複雜性是當我有一些特徵的一些不同的公式。

例如:性狀YLD有一個公式,我必須計算它的值,這也可能取決於其他一些特徵。每種不同的作物都可以有不同的特性。

所有這些我都可以做到 - 每當用戶選擇裁剪時,我會檢查這些特定的特徵並進行計算(如果它不是特殊的特徵,那麼我根據數據庫條目對其進行平均或求和),但有很多硬編碼。 我想對處理此問題的更好方法提出建議。

我的代碼需要處理簡單和複雜的計算。 簡單的計算很容易,我已經取得了爲特徵輸入的值的平均值。 當我必須做複雜的計算時,問題出現了,因爲每個作物都有自己的公式,所以要計算我必須檢查作物,然後檢查複雜的特徵。所以我必須對複雜特徵的特徵名稱進行硬編碼。 可以告訴我如何使用Java oops [?!?]設計它,這樣我就可以使它成爲通用的?

我有大約10種不同的作物。有人算了一筆賬是針對農作物,所以會有大量的代碼,如若跌破:

hasZeroValue = (HashMap<String, ArrayList<String>>) dataValues[1]; 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("TLSSG_70")) { 
    traitAvg=calculateTLCV(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues,50); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("TLSSG_100")) { 
    traitAvg=calculateTLCV(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues,50); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_60")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_90")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_120")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_60")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_90")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_120")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_60")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_90")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_120")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg, dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("ELCV_60")) { 

如果類每種作物被寫,把它作爲應用程序,它支持109種莊稼,現在每個用戶登錄到系統,我有鏈接,他可以做到這一點以上的鍛鍊,是否更好,作物是一個階級。每種作物都有100個性狀,這也是每個特徵。請讓我知道。

回答

0

整體解決方案取決於您沒有告訴我們的細節。我們不知道您是否希望爲複雜計算編寫代碼,這意味着您可以爲每個作物創建一個類,或者您希望能夠添加一個作物或更改計算而無需更改代碼。

但是,您正在做的一些事情可以改進。你的if a && b then x else if a && c then y else if a && d等模式,可以改爲:

if a 
{ 
    if b { x } 
    else if c { y } 

... 
} 

更重要的是,假設你可以做類作物和/或計算,可以存儲這樣的對象的集合,並用它們來代替if/then/else序列。例如:創建由上面的'traitName'值索引的對象的散列表;而不是if/then/else,使用HashMap.get()獲取對相應對象的引用,並將計算方法放入該對象中。

我想你可以稱這些設計模式,但這不是通常所說的術語。

2

封裝性狀和作物成單獨的類首先,你可能想創建一個像Crop.classTrait.class其中將包含基本骨架和共同的東西都有些抽象類作物或特性,然後你可以擴展這些類併爲每個特定的作物或特性製作一個單獨的類,這樣特定的類將包含特定於該作物或特性的信息和過程,並且仍然保持Crop.class和Trait的一般功能.class。

您還可以爲單個或一組操作創建類似的模式,例如您需要對這些特徵執行操作。

這裏的想法是以更可維護的方式將其分散出來,這將使添加更多作物和特性或修改現有的作物變得輕而易舉。


編輯:

如果你有作物/性狀的任意號碼,然後寫每種作物單獨的類不打算在這裏是解決方案。農作物的個性將來自更廣義的階級的某些屬性和狀態。然而,如果某些作物/性狀具有相似/相同的功能/特性(我認爲他們會提起大約100種作物/特性等),那麼可以將它們分組在一個單獨的課堂上。 (GrainCrop.class或沿行的東西)

這意味着,你還是會希望有Crop.classTrait.class抽象的,但不是每種作物分組到一個單獨的類你可以將它們組合成類似作物的包裝,這樣可以讓你輕鬆訪問或限制作物的某個子集。

此外,您仍然可以簡化某些任務,使其看起來不那麼龐大,甚至可能將它們分散到不同的類中。

從你的例子,如果我們分析一下,我們可以看到,大多數重複性質有作物的ID(cropId.equalsIgnoreCase("OK")cropId.equalsIgnoreCase("TO")

所以不是無數次檢查作物ID是「TO」或「OK 「你可以檢查一次,並有2個獨立的分支來檢查」TO「屬性和」OK「屬性。

此外,如果可能還有一些農作物具有相同的一套共同操作的,那麼你可以將它們分組下BasicCropOperations.class,然後也許瓜分複雜操作的其餘部分爲類似的行爲像套EnvironmentalCropOperations.class什麼如果例如有涉及熱量和溼度的事情。

雖然這個想法仍然是一樣的,但在合理範圍內將所有內容都劃分爲更小的模塊。 (例如:爲不同作物/特性編寫200個課程是不合理的)

+0

我在上面的問題結尾添加了幾點,請看看它。 – Vividata

+0

@vividata此解決方案應涵蓋該編輯 – Pureferret

0

關於這種被視爲輕浮答案或根本不應答的風險...... 不要使用Java,因此請使用Scala或像Ruby這樣的動態語言。您甚至在Scala中使用了正確的名稱:「特質」。

設計模式可能很有用,但是一旦它們不是爲了方便起見而使用,而是爲了解決語言適合解決問題的嚴重缺陷,我認爲是時候跳躍技術了。