链式if语句的模式

时间:2014-06-13 12:30:05

标签: c# design-patterns if-statement

我正在制作吉他和弦发现器应用程序。我用一个多维数组来表示指板。数组中的每个元素都由一个FretSpace结构表示,该结构具有字符串属性'注意'。为了在指板上初始化音符属性,我将吉他弦的细节与指板一起传递。这项工作是在GuitarTuner类中完成的。这是FretSpace类: -

public struct FretSpace : IPlottable, IResourceConsumer
{
    public string Note { get; set; }

    public int XPos { get; set; }

    public int YPos { get; set; }

    public string ResourceName { get; set; }


    public override string ToString()
    {
        return string.Format("[{0}] Note:{1} XPos:{2} YPos{3} ResourceName:{4}",
            GetType().Name, Note, XPos, YPos, ResourceName);
    }
}

吉他调音器类一次调整一个字符串。在这种情况下,调整意味着使用正确的音符位置初始化每个FretSpace Note属性。在TuneString方法中,我检查我们正在处理的字符串并返回要应用于所选字符串的注释列表。我看看我的代码,它闻起来很大。这是TuneString方法的违规部分: -

public void TuneString(GuitarString stringToTune, FretSpace[,] fretboard)
    {
        List<string> notes = null;

        if (stringToTune == GuitarString.ELow)
        {
            notes = _scaleGenerator.GetScale(Scale.E).ToList();
        }
        if (stringToTune == GuitarString.A)
        {
            notes = _scaleGenerator.GetScale(Scale.A).ToList();
        }
        if (stringToTune == GuitarString.D)
        {
            notes = _scaleGenerator.GetScale(Scale.D).ToList();
        }
        if (stringToTune == GuitarString.G)
        {
            notes = _scaleGenerator.GetScale(Scale.G).ToList();
        }
        if (stringToTune == GuitarString.B)
        {
            notes = _scaleGenerator.GetScale(Scale.B).ToList();
        }
        if (stringToTune == GuitarString.EHigh)
        {
            notes = _scaleGenerator.GetScale(Scale.E).ToList();
        } //carry on and tune the string using the notes we returned

我不是设计模式大师,但我正在迅速获得代码气味的敏锐鼻子。有没有更好的方法来实现这一点,因为每次调用相同的方法,但只有一个不同的参数。我看着Command。似乎不适用于返回值的地方,但如果我错了,请纠正我。我也看过工厂,但这似乎与回归一系列物体有关,在这种情况下并不适用。我在一小时的最佳时间内搜索了堆栈溢出,但似乎找不到相关的例子。谁能帮忙。感谢。

1 个答案:

答案 0 :(得分:6)

我个人会创建一个Dictionary<GuitarString, Scale>并在那里存储字符串和刻度之间的映射。然后你可以简单地在那里查找字符串以获得比例。

e.g。

var stringToScaleMap = new Dictionary<GuitarString, Scale>
                           { 
                               { GuitarString.ELow, Scale.E }
                               , { GuitarString.A, Scale.A }
                               // etc...
                           }

var scale = stringToScaleMap[stringToTune];
notes = _scaleGenerator.GetScale(scale).ToList();

您可以将地图存储在配置中,或者只是将其硬编码到项目中的某个位置。由于映射不太可能改变,后者可能是最简单的选择。