2016-06-17 55 views
0

類測試是abstract。它包含一個基本的測試名和一個分數。該分數(雙倍)可通過名爲TestScore的屬性訪問。重構重複代碼 - 唯一區別是<符號

三類繼承自Test。他們是不同的,每種測試都有不同的評分方式。

目標:根據評分可以在的值之間的範圍值,評分與6評分之一。

class ScoreRangeAscendingTest : Test 
{ 
    public ScoreRangeAscendingTest(double score, Enums.TestType typeName) : base(score, typeName) { } 
    public double[] ranges; 
    public Enums.Rating calculateScore(double[] range) 
    { 
     if (scoreInVeryWeakRange()) 
      return Enums.Rating.VeryWeak; 
     else if (scoreInWeakRange()) 
      return Enums.Rating.Weak; 
     else if (scoreInAveragelyWeakRange()) 
      return Enums.Rating.AveragelyWeak; 
     else if (scoreInAveragelyGoodRange()) 
      return Enums.Rating.AveragelyGood; 
     else if (scoreInGoodRange()) 
      return Enums.Rating.Good; 
     else 
      return Enums.Rating.VeryGood; 
    } 

    private bool scoreInVeryWeakRange() 
    { 
     return this.TestScore < ranges[(int)Enums.Border.P10]; 
    } 
    private bool scoreInWeakRange() 
    { 
     return TestScore >= ranges[(int)Enums.Border.P10] && TestScore < ranges[(int)Enums.Border.P25]; 
    } 
    private bool scoreInAveragelyWeakRange() 
    { 
     return TestScore >= ranges[(int)Enums.Border.P25] && TestScore < ranges[(int)Enums.Border.P50]; 
    } 
    private bool scoreInAveragelyGoodRange() 
    { 
     return TestScore >= ranges[(int)Enums.Border.P50] && TestScore < ranges[(int)Enums.Border.P75]; 
    } 
    private bool scoreInGoodRange() 
    { 
     return TestScore >= ranges[(int)Enums.Border.P75] && TestScore < ranges[(int)Enums.Border.P90]; 
    } 
    private bool scoreInVeryGoodRange() 
    { 
     return TestScore > ranges[(int)Enums.Border.P90]; 
    } 

} 

}

問題:我的測試,其相應的範圍上去測試其相應的範圍下去。因此,我需要爲第二種測試編寫完全相同的代碼,但這次所有'<'符號都必須是'>'符號,反之亦然。

問題:如何避免重複此代碼?有沒有可能將其添加到基類?

+1

包含重複的測試代碼會很有幫助;這裏測試調用的代碼並沒有告訴我們很多。 – GendoIkari

+0

重複的是私有bool函數的列表 - 每種情況下唯一的區別是< becoming >,反之亦然。 已經給出瞭解決方案:-) –

+0

我不明白你的問題。您發佈的代碼與< becoming >不同。 – GendoIkari

回答

2

我不是100%確定我收到了問題,但您可能可以使用委託來執行比較。

下應該相當於你的當前代碼:

class ScoreRangeAscendingTest : Test 
{ 
    public ScoreRangeAscendingTest(double score, Enums.TestType typeName) : base(score, typeName) { } 
    public double[] ranges; 
    public Enums.Rating calculateScore(double[] range) { 
     Func<double, double, bool> cmp = (x, y) => x < y; // you can swap the comparison here, e.g. (x, y) => x > y 
     if (scoreInVeryWeakRange(cmp)) 
      return Enums.Rating.VeryWeak; 
     else if (scoreInWeakRange(cmp)) 
      return Enums.Rating.Weak; 
     else if (scoreInAveragelyWeakRange(cmp)) 
      return Enums.Rating.AveragelyWeak; 
     else if (scoreInAveragelyGoodRange(cmp)) 
      return Enums.Rating.AveragelyGood; 
     else if (scoreInGoodRange(cmp)) 
      return Enums.Rating.Good; 
     else 
      return Enums.Rating.VeryGood; 
    } 

    private bool scoreInVeryWeakRange(Func<double, double, bool> cmp) 
    { 
     return cmp(this.TestScore, ranges[(int)Enums.Border.P10]); 
    } 
    private bool scoreInWeakRange(Func<double, double, bool> cmp) 
    { 
     return !cmp(TestScore, ranges[(int)Enums.Border.P10]) && cmp(TestScore, ranges[(int)Enums.Border.P25]); 
    } 
    private bool scoreInAveragelyWeakRange(Func<double, double, bool> cmp) 
    { 
     return !cmp(TestScore, ranges[(int)Enums.Border.P25]) && cmp(TestScore, ranges[(int)Enums.Border.P50]); 
    } 
    private bool scoreInAveragelyGoodRange(Func<double, double, bool> cmp) 
    { 
     return !cmp(TestScore, ranges[(int)Enums.Border.P50]) && cmp(TestScore, ranges[(int)Enums.Border.P75]); 
    } 
    private bool scoreInGoodRange(Func<double, double, bool> cmp) 
    { 
     return !cmp(TestScore, ranges[(int)Enums.Border.P75]) && cmp(TestScore, ranges[(int)Enums.Border.P90]); 
    } 
    private bool scoreInVeryGoodRange(Func<double, double, bool> cmp) 
    { 
     return (TestScore == ranges[(int)Enums.Border.P90]) || !cmp(TestScore, ranges[(int)Enums.Border.P90]); 
    } 

} 

然而,由於在加評論指出,現在你可以使用不同的比較函數,也就是說,交換你<>

+0

哇!你們真的很快就陷入了我的問題! 最後我得到了和你一樣的答案。令人難以置信的那些代表。 我最大的問題是提出正確的問題:) 我在繼承類中進行比較,因爲它們存在特定於此目的的類。 –

1

System.Double實施IComparable<double>。所以,如果你有幾行代碼,這不同之處僅比較操作符,你可以寫這樣的事情:

abstract class ComparisonBase 
{ 
    protected bool IsSatisfiesCondition(double left, double right, params int[] conditions) 
    { 
     return conditions.Contains(left.CompareTo(right)); 
    } 

    public abstract bool Compare(double left, double right); 
} 

class GreaterThan : ComparisonBase 
{ 
    public override bool Compare(double left, double right) 
    { 
     // instead of left > right 
     return IsSatisfiesCondition(left, right, 1); 
    } 
} 

class LessThan : ComparisonBase 
{ 
    public override bool Compare(double left, double right) 
    { 
     // instead of left < right 
     return IsSatisfiesCondition(left, right, -1); 
    } 
} 

class GreaterThanOrEqual : ComparisonBase 
{ 
    public override bool Compare(double left, double right) 
    { 
     // instead of left >= right 
     return IsSatisfiesCondition(left, right, 1, 0); 
    } 
} 

這只是樣品,但它應該給你一個想法如何在實際應用它碼。

+0

這可能有效,但我自己與代表和lambda函數一起使用。我不能把票投給你們兩個 - 這太遺憾了! –

+0

請注意''CompareTo''可能返回任何整數,而不僅僅是'-1','0','1',所以你的解決方案可能不會按預期工作而不需要修改,參見[MSDN reference](https:// msdn。 microsoft.com/en-us/library/43hc6wht%28v=vs.110%29.aspx)。 – Lucero

+0

@Lucero:是的,一般來說,比較結果必須包含在'Math.Sign'中。但對於像'double'這樣的原始類型,則會有-1,0,1,AFAIK。 – Dennis