如何重构两种方法?

时间:2016-11-22 18:38:18

标签: c# .net refactoring

我有两种类似签名的方法(ChooseChamfer和ChooseFillet)。如果.. else,这些方法有广泛的结构。 (我带了一个简化版本),调用方法(CreateChamfer和CreateFillet)。如何在单个方法中重构代码?

private void ChooseChamfer(string featureType, double diameter, double distance, string str1, string str2)
{
    if (featureType.Contains("F"))
    {
        CreateChamfer(diameter, 
            distance,
            -double.Parse(str1, System.Globalization.CultureInfo.InvariantCulture),
             double.Parse(str2, System.Globalization.CultureInfo.InvariantCulture));
    }
    else if (featureType.Contains("L"))
    {
        CreateChamfer(diameter, 
            distance,
            double.Parse(str1, System.Globalization.CultureInfo.InvariantCulture),
           -double.Parse(str2, System.Globalization.CultureInfo.InvariantCulture));
    }
}

private void ChooseFillet(string featureType, double diameter, double distance, string str1)
{
    if (featureType.Contains("F"))
    {
        CreateFillet(diameter, 
            distance,
            -double.Parse(str1, System.Globalization.CultureInfo.InvariantCulture));
    }
    else if (featureType.Contains("L"))
    {
        CreateFillet(diameter, 
            distance,
            double.Parse(str1, System.Globalization.CultureInfo.InvariantCulture));
    }
}

private void CreateChamfer(double diameter, double distance, double str1, double str2)
{
    //Draw Chamfer
}

private void CreateFillet(double diameter, double distance, double str1)
{
    //Draw Fillet
}

提前谢谢。

1 个答案:

答案 0 :(得分:0)

我不知道你想要削减多深,但每当我看到其他复杂性时,我认为工厂和专家。这可以通过100种不同的方式进行切割,但是根据我对潜在复杂性的理解,我认为基于FeatureType的工厂将比将其基于Chamfer / Fillet更好:

abstract class GraphicAttributes
{
    public double Diameter { get; protected set; }
    public double Distance { get; protected set; }
    public double Str1 { get; protected set; }
    public double? Str2 { get; protected set; }

    public GraphicAttributes(double diameter, double distance, string str1, string str2)
    {
        // load all attributes plain-vanilla - let the subclasses adjust as necessary
        Diameter = diameter;
        Distance = distance;
        Str1 = double.Parse(str1, System.Globalization.CultureInfo.InvariantCulture);
        Str2 = String.IsNullOrEmpty(str2)
            ? new Nullable<double>()
            : double.Parse(str2, System.Globalization.CultureInfo.InvariantCulture);
    }
}

class FeatureTypeF : GraphicAttributes
{
    public FeatureTypeF(double diameter, double distance, string str1, string str2)
        : base(diameter, distance, str1, str2)
    {
        Str1 = -Str1;
    }
}

class FeatureTypeL : GraphicAttributes
{
    public FeatureTypeL(double diameter, double distance, string str1, string str2)
        : base(diameter, distance, str1, str2)
    {
        if (Str2.HasValue)
            Str2 = new Nullable<double>(-(Str2.Value));
    }
}

class GraphicAttributeFactory
{
    public static GraphicAttributes GetGraphicAttributes(string featureType, double diameter, double distance, string str1, string str2)
    {
        if (featureType.Contains("F"))
            return new FeatureTypeF(diameter, distance, str1, str2);

        if (featureType.Contains("L"))
            return new FeatureTypeL(diameter, distance, str1, str2);

        // add more implementations here

        throw new Exception("Unexpected featureType!");
    }
}

// and then your final method looks like:

private void Choose(string featureType, double diameter, double distance, string str1, string str2)
{
    GraphicAttributes ga = GraphicAttributeFactory.GetGraphicAttributes(featureType, diameter, distance, str1, str2);

    if (ga.Str2.HasValue)
        CreateChamfer(ga.Diameter, ga.Distance, ga.Str1, ga.Str2.Value);
    else
        CreateFillet(ga.Diameter, ga.Distance, ga.Str1);
}

调用者必须明确地使额外的参数无效:

Choose("__L_", 12.0, 5.0, "123", "456"); // chamfer
Choose("__F_", 12.0, 5.0, "123", null);  // fillet

那部分有点笨拙;它可以扩展为使用&#39; params string&#39;。

此外,如果您可以更深入地将Create ..()方法重构为直接获取GraphicAttribute实例的方法,那将会很棒。

无论如何,真正的想法是将属性的特定处理放入专业课程中,每个人都知道如何处理它自己的情况,然后知道如何选择正确的实现。