2016-11-22 1 views
0

Ich habe zwei Methoden mit einer ähnlichen Signatur (ChooseChamfer und ChooseFillet). Diese Methoden haben eine umfangreiche Struktur wenn .. sonst. (Ich brachte eine vereinfachte Version), wo die Methoden aufgerufen werden (CreateChamfer und CreateFillet). Wie kann ich Refactoring-Code in einer einzigen Methode machen?Wie man zwei Methoden umgestaltet?

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 
} 

Vielen Dank im Voraus.

+1

Ich denke, dass [http://codereview.stackexchange.com/](http://codereview.stackexchange.com/) ist besser Ort für diese Art von Frage – Fabio

+0

Sie könnten mit Reflection ('MethodInfo') aber dann arbeiten Sie sind anfällig für Laufzeitausnahmen. Oder du bewegst den int rückwärts in eine separate Methode. – NtFreX

+0

Haben 'Chamfer' und' Fillet' eine gemeinsame Basisklasse? Wenn so eingeschränkt Generika die Dinge ein wenig vereinfachen könnten. Auch wenn Sie eine große Menge von if-else haben, die auf 'featureType' prüft, können Sie das in ein 'Dictionary' umformulieren, wobei der Wert die Methode ist, die aufgerufen werden soll, oder der' Type' – KMoussa

Antwort

0

Ich weiß nicht, wie tief Sie schneiden möchten, aber wenn ich sehe, dass/sonst Komplexität so, denke ich Factory und Spezialisten. Diese 100 geschnitten werden könnte unterschiedliche Weise, aber von dem, was ich von der möglichen Komplexität verstehen, ich glaube, eine Fabrik auf Feature stützen wäre besser, als es auf Fasen/Abrunden stützen:

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); 
} 

Der Anrufer ausdrücklich hätte zunichte machen die zusätzliche param:

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

Dieser Teil Art ungeschickt ist; es könnte erweitert werden, um 'params string' zu verwenden.

Auch wäre es großartig, wenn Sie tiefer gehen und die Create ..() -Methoden in eine umgestalten könnten, die die GraphicAttribute-Instanz direkt übernimmt.

In jedem Fall besteht die eigentliche Idee darin, die spezifische Behandlung der Attribute in Spezialklassen zu unterteilen, von denen jeder weiß, wie er mit seiner eigenen Situation umgehen soll, und dann eine Fabrik, die die richtige Implementierung zu wählen weiß.

Verwandte Themen