2014-03-31 35 views
0

這是一個簡單的例子,我想先揭示問題。優雅的數字 - >字母學術成績映射

考慮你有一堆數字,範圍從0到10,並且你想把它們映射到字母等級(A,B,C,D,F)。

可以編寫一個if語句序列,測試相應字母範圍內的給定數字並返回正確的字母。

問題是:什麼模式可以用來使這個更強大,也許更多的解耦?例如,如果我有10個數字範圍而不是5個數字範圍,那麼我將不得不編輯這個單一方法來添加其他5個個案。我也不能保證我的範圍是排他性的,儘管它們應該屬於這種情況。

我可以想象在這裏使用的排序的Dictionary<Range<int>, string>>,但它仍然不足以提供我正在尋找的所有保證。也許人們可以用多態性來以更簡潔和可擴展的方式對這個概念進行建模?

我很抱歉這個簡單的例子,但我相信這可以作爲一種通用的範圍映射策略適用於其他更復雜的算法。

回答

1

如果它是像將位置映射到位置線性增加並且結果增加相同數量的其他格式那樣簡單的事情,那麼可以使用簡單的公式。

對於你的等級信例如,映射「A」爲0,「B」 1等很簡單:

int value = ... 
Character result = value -'A'; 

大多數語言將「A」映射到它的ASCII值,減去你想要的值從'A'將產生字母「過去」A的數量。

如果您需要像範圍映射那樣更復雜的事情,那麼Replace Conditional Dispatcher with Command模式(示例here)可能是個好主意。

如果你有更復雜的東西,然後像Chain of Responsibility模式。

這裏有一個簡單的例子:

你需要做,有一個方法來確定您所提供的範圍將這種執行工作的接口。

IGradeMapper{ 
    bool accept(Range<int>); 

    String computeGrade(Range<int>); 
} 

那麼你有是爲了檢查的IGradeMapper個清單:

for(IGradeMapper mapper : list){ 
    if(mapper.accept(range)){ 
     return mapper.computeGrade(range); 
    } 
} 

關於這種方式的好處是匹配器均loosley耦合,並且可以實現與中添加新的如果你願意,可以在後面的列表中(即使在運行時)。

如果您是這兩種模式中的任何一種,那麼嘗試使第一個測試條件最爲常見,以使其運行速度更快。

+0

非常好,正是我希望看到的那種答案。不幸的是,這不是一個計算關係,因爲我特別提到了問題中的學術成績。你能否在這裏設計一個使用責任鏈模式的簡單例子? – julealgon

+0

@julealgon更新回答 – dkatzel

+0

我剛剛注意到你在OP上的編輯,對此抱歉。另外,我認爲你的'IGradeMapper'應該使用'int'而不是'Range '。這裏的意圖是將單個數字映射到等級,因爲例如A的範圍是9-> 10。我想知道在這種情況下會有什麼更好的效果:我可以在構造函數中創建多個傳遞區間和相應字母的映射器,或者創建一些具有硬編碼內部區間和範圍的具體類型。 – julealgon