Question

J'avais un cours qui avait beaucoup de méthodes:

public class MyClass {
    public bool checkConditions() {
        return checkCondition1() &&
               checkCondition2() &&
               checkCondition3();
    }

...conditions methods

    public void DoProcess() {
        FirstPartOfProcess();
        SecondPartOfProcess();
        ThirdPartOfProcess();
    }

...process methods
}

J'ai identifié deux domaines de travail "vitaux" et j'ai décidé d'extraire ces méthodes à ses propres classes:

public class MyClass {
    private readonly MyClassConditions _conditions = new ...;
    private readonly MyClassProcessExecution = new ...;

    public bool checkConditions() {
        return _conditions.checkConditions();
    }

    public void DoProcess() {
        _process.DoProcess();
    }
}

À Java, je définirais MyClassConditions et MyClassProcessExecution comme package protected, mais je ne peux pas faire ça en C #.


Comment allez-vous faire cela en C #?

Définir les deux classes comme classes intérieures de MyClass?

J'ai 2 options: je les définis à l'intérieur MyClass, avoir tout dans le même fichier, qui a l'air déroutant et laid, ou je peux définir MyClass comme un partial class, avoir un fichier pour MyClass, autre pour MyClassConditions et autre pour MyClassProcessExecution.

Les définir comme internes?

Je n'aime pas vraiment autant du modificateur interne, car je ne trouve pas que ces classes ajoutent aucune valeur pour le reste de mon programme / assemblage, et je voudrais les cacher si possible. Ce n'est pas comme s'ils seraient utiles / réutilisables dans toute autre partie du programme.

Les garder comme publics?

Je ne vois pas pourquoi, mais j'ai laissé cette option ici.

Tout autre?

Nomme le!

Merci

Était-ce utile?

La solution

Votre meilleur pari est probablement d'utiliser des classes partielles et de mettre les trois touffes de code dans des fichiers séparés ajoutant à la même classe. Vous pouvez ensuite rendre le code conditionnel et de traitement privé afin que seule la classe elle-même puisse y accéder.

Autres conseils

Pour les classes de type "Helper" qui ne seront pas utilisées en dehors de l'assemblage actuel, Internal est la voie à suivre si les méthodes vont être utilisées par plusieurs classes.

Pour les méthodes qui ne seront utilisées que par une seule classe, je les rendrais simplement privées à la classe ou utiliserais des classes intérieures si c'est en fait une classe qui n'est pas utilisée ailleurs. Vous pouvez également prendre en compte le code dans des méthodes statiques si le code ne s'appuie pas sur des membres (non statiques) de votre classe.

Je peux définir MyClass comme une classe partielle, ayant un fichier pour myClass, un autre pour MyClassConditions et autres pour MyClassProcessExecution.

C'est peut-être mon arrière-plan C ++, mais c'est mon approche standard, bien que je regroupe les classes de petites assises ensemble en un seul fichier.

Ainsi, sur l'un de mes projets actuels, le Product La classe est divisée entre Product.cs et ProductPrivate.cs

Je vais pour autre chose - la question du public / protégé / privé peut ne pas être résolu spécifiquement par cela, mais je pense que cela se prête beaucoup mieux à la maintenance que de nombreuses classes internes imbriquées.

Comme il semble que vous ayez un ensemble d'étapes dans un algorithme séquentiel, où l'exécution d'une étape peut ou non dépendre de l'exécution de l'étape précédente. Ce type de traitement d'étape séquentiel peut parfois utiliser le Chaîne de responsabilité Modèle, bien qu'il soit un peu transformé de son intention d'origine. Focus uniquement sur votre "méthode de traitement", par exemple, à partir de quelque chose comme ci-dessous:

class LargeClass
{
public void DoProcess()
{
  if (DoProcess1())
  {
    if (DoProcess2())
    {
      DoProcess3();
    }
  }
}

protected bool DoProcess1()
{
...
}

protected bool DoProcess2()
{
...
}

protected bool DoProcess3()
{
...
}

}

En utilisant la chaîne de responsabilité, cela pourrait être décomposé en un ensemble de classes concrètes pour chaque étape, qui héritent d'une classe d'étape abstraite. La classe d'étape abstraite est plus responsable de s'assurer que l'étape suivante est appelée si les conditions préalables nécessaires sont remplies.

public class AbstractStep
{
    public AbstractStep NextStep { get; set; }

    public virtual bool ExecuteStep
    {
       if (NextStep != null)
       {
         return NextStep.ExecuteStep();
       }
    }  
}

public class ConcreteStep1 : AbstractStep
{
    public bool ExecuteStep
    {
       // execute DoProcess1 stuff
       // call base
       return base.ExecuteStep();
    }
}

...

public class ConcreteStep3 : AbstractStep
{
     public bool ExecuteStep
     { 
        // Execute DoProcess3 stuff
        // call base
        return true; // or false?
      }
}

Pour configurer cela, vous feriez, dans une partie du code, procéder à ce qui suit:

var stepOne = new ConcreteStep1();
var stepTwo = new ConcreteStep2();
var stepThree = new ConcreteStep3();
stepOne.NextStep = stepTwo;
stepTwo.NextStep = stepThree;

bool success = stepOne.ExecuteStep();

Cela peut aider à nettoyer le ballonnement de code que vous avez dans votre classe unique - je l'ai utilisé pour quelques algorithmes de type séquentiel dans le passé et il a aidé à isoler chaque étape bien. Vous pouvez évidemment appliquer la même idée à votre vérification de l'état (ou les construire dans chaque étape, si cela s'applique). Vous pouvez également faire une variation à ce sujet en termes de passage de l'état entre les étapes en faisant en sorte que la méthode ExecuteTEP prenne un paramètre avec un objet d'état d'une certaine sorte.

Bien sûr, si ce qui vous préoccupe vraiment dans ce post, c'est simplement cacher les différentes étapes, alors oui, vous pouvez faire de chacun de vos sous-étapes une classe protégée au sein de votre classe qui crée les étapes. À moins que vous exposiez votre bibliothèque à des clients sous une forme ou une manière, et vous ne voulez pas qu'ils aient un type de visibilité dans vos étapes d'exécution, cela semble être une préoccupation plus petite puis rendre le code maintenable.

Créez les classes avec le même modificateur d'accès que les méthodes que vous avez refactorisées. Les classes partielles ne sont vraiment utiles que lorsque vous avez plusieurs personnes ou des outils de génération de code Automat5d modifiant fréquemment les mêmes classes. Ils évitent vraiment la source de la source où votre contrôleur source écrase votre code car il ne peut pas fusionner plusieurs modifications au même fichier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top