2

i besoin d'aide refactoring la classe suivante,Comment éviter à long interrupteur ..need aider refactoring

Voici une opération de classe avec la variété des opérations dans le commutateur: je veux éviter l'interrupteur lire quelques articles statement.I sur l'utilisation du polymorphisme et le modèle d'état .mais quand je refactorise les classes je n'ai pas accès à beaucoup de variables, propriétés
Je suis confus sur l'utilisation de l'opération comme classe abstraite ou pour implémenter une interface.
Je voulais juste savoir quel type de refactoring aidera dans ce cas
polymorphisme ou modèle d'état?
Et quand les utiliser?

public class Operation 
    { 
     public enum OperationType 
     { 
      add, 
      update, 
      delete, 
      retrieve 
     } 
     public enum OperationStatus 
     { 
      Success, 
      NotStarted, 
      Error, 
      Fail, 
      InProcess, 
      Free 
     } 

    // raise this event when operation completes 
    public delegate void OperationNotifier(Operation operation); 
    public event OperationNotifier OperationEvent=null;   

    private OperationStatus _status=OperationStatus.Free; 
    public OperationStatus Status 
    { 
     get { return _status; } 
     set { _status = value; } 
    }  


    private string _fileName = null; 

    public string FileName 
    { 
     get { return _fileName; } 
     set { _fileName = value; } 
    } 

    private string _opnid = null; 

    public string OperationId 
    { 
     get { return _opnid; } 
     set { _opnid = value; } 
    } 

    private OperationType _type; 
    public OperationType Type 
    { 
     get { return _type; } 
     set { _type = value; } 
    } 

    public void performOperation(OperationType type, string parameters) 
    { 

     switch (type) 
     { 
      case OperationType.add: 
       _status = addOperation(parameters);     
       break; 
      case OperationType.update: 
       _status = updateOperation(parameters); 
       break; 
      case OperationType.delete: 
       _status = deleteOperation(parameters); 
       break; 
      case OperationType.retrieve: 
       _status = retrieveOperation(parameters); 
       break; 
      default: 
       break; 
     } 
     if (OperationEvent != null) 
      OperationEvent(this);   
     // return true; 
    } 


    public OperationStatus addOperation(string parameters) 
    {   
     DateTime start = DateTime.Now; 
     //Do SOMETHING BIG 
     TimeSpan timeTaken = DateTime.Now - start; 
     System.Diagnostics.Debug.WriteLine("addOperation:-" + _opnid + "-" + _fileName + "--" + timeTaken.Milliseconds); 
     return OperationStatus.Success; 

     } 
...other operations here.... 

Indicatif téléphonique est similaire à:

Operation oprnObj; 
       Operation.OperationType operationType; 

oprnObj = new Operation(); 
oprnObj.FileName = String.Concat("myxmlfile",".xml"); 
oprnObj.OperationId = oprnid; 
oprnObj.OperationEvent += new Operation.OperationNotifier(oprnObj_OperationEvent); 
operation="add"; //get From Outside function getOperation() 
operationType = (Operation.OperationType)Enum.Parse(typeof(Operation.OperationType), operation.ToLower(), true); 
oprnObj.Type = operationType; 
oprnObj.performOperation(operationType, parameters); 

Références Sujets:
Link
Link
..many plus.

Répondre

2

En C#, vous pouvez utiliser les fonctions de la stratégie, et en utilisant une méthode d'extension que la fonction vous donne la possibilité d'ajouter des opérations en cas de besoin:

public enum OperationStatus 
{ 
    Success, NotStarted, Error, Fail, InProcess, Free 
} 

public class Operation 
{ 
    // raise this event when operation completes 
    public delegate void OperationNotifier(Operation operation, OperationStatus status); 
    public event OperationNotifier OperationEvent = null; 

    public string FileName { get; set; } 
    public string OperationId { get; set; } 

    public Func<string, OperationStatus> Function { get; set; } 

    public void PerformOperation(string parameters) 
    { 
     OperationStatus status = Function(parameters); 

     if (OperationEvent != null) 
      OperationEvent(this, status); 
    } 
} 

static class AddOp 
{ 
    public static OperationStatus AddOperation(this Operation op, string parameters) 
    { 
     DateTime start = DateTime.Now; 
     //Do SOMETHING BIG 
     TimeSpan timeTaken = DateTime.Now - start; 
     System.Diagnostics.Debug.WriteLine("addOperation:-" + op.OperationId + "-" + op.FileName + "--" + timeTaken.Milliseconds); 
     return OperationStatus.Success; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Operation oprnObj = new Operation(); 
     oprnObj.FileName = String.Concat("myxmlfile", ".xml"); 
     oprnObj.OperationId = "oprnid"; 
     oprnObj.OperationEvent += new Operation.OperationNotifier(oprnObj_OperationEvent); 
     string parameters = "fish"; 
     oprnObj.Function = oprnObj.AddOperation; 
     oprnObj.PerformOperation(parameters); 
    } 

    public static void oprnObj_OperationEvent(Operation op, OperationStatus status) 
    { 
     Console.WriteLine("{0} returned {1}", op.Function.Method.Name, status); 
    } 
} 

Vous pouvez également passer la OperationEvent à la fonction si vous voulez des mises à jour de statut intermédiaires.

+0

Im actuellement utilisant .net 2.0? Je pense que la méthode d'extension est en 3.0. peut quelque chose smiliar être fait en 2.0. – Amitd

+0

Vous pouvez utiliser des méthodes d'extension avec .Net 2.0. Tant que vous utilisez C# 3 (que vous pouvez si vous avez VS2008) – philsquared

+0

nah à partir de maintenant toujours en utilisant VS2005.but thx pour info :) – Amitd

1

Je pense que vous êtes sur la bonne voie en essayant d'utiliser le polymorphisme ici. Cela devrait vous conduire au modèle Strategy. Refactoriser les opérations spécifiques en sous-classes (AddOperation, etc), mais aussi (et c'est l'étape qui vous manque probablement), factoriser les données (nom de fichier, etc), dans un objet séparé qui est passé à chaque opération .

Je créerais à la fois une interface d'opération, ainsi qu'une OperationBase qui contiendrait l'état.

+0

le code appelant initialise-t-il les membres de la classe OperationBase? ou cette classe doit-elle être dans l'interface en tant que paramètre de méthode? – Amitd

+0

Les seuls membres de la classe qui ont besoin d'une initialisation seront dans votre classe de données, maintenant séparée, qui n'a pas besoin d'être polymorphe. Le seul état que je verrais les classes d'opération ayant besoin serait le drapeau d'état - qui devrait être initialisé en interne – philsquared

+0

je suis toujours confus mais THX je vais l'essayer ... je pense im beaucoup plus proche cette fois. – Amitd

0

J'aimerais que vous vérifiiez si ce commutateur est susceptible d'apparaître à plusieurs endroits. Si c'est juste isolé à un endroit, vous pouvez choisir de vivre avec cela. (Les alternatives sont plus complexes).

Toutefois, si vous avez besoin de faire le changement,
Visitez le lien suivant - http://refactoring.com/catalog/index.html
Chercher « Remplacer Type de code », il y a 3 refactorisations possibles que vous pouvez utiliser. À mon humble avis la stratégie est celle dont vous avez besoin.