web-dev-qa-db-fra.com

Meilleure pratique pour une chaîne constante pour les implémentations à utiliser

Disons que j'ai une interface:

public interface IFeature
{
    Task execFeature();
}

et deux implémentations:

public class FirstFeature : IFeature
{
    private IWebApi webApi;
    public FirstFeature(IWebApi webApi)
    {
        this.webApi = webApi;
    }

    public async Task execFeature()
    {
        string response = await webApi.getClassName();
        IResult result;
        if(response==null)
            result = new TextResult("Error accessing api - check internet connection/api address");
        else
            result = new TextResult("Hello dear user – the selected class name is " + response);
        result.display();
    }
}

public class SecondFeature : IFeature
{
    private IWebApi webApi;
    public SecondFeature(IWebApi webApi)
    {
        this.webApi = webApi;
    }

    public async Task execFeature()
    {
        List<string> classNames = new List<string>();
        var classNameTasks = Enumerable.Range(1, 3).Select(i => webApi.getClassName()).ToArray();
        classNames.AddRange((await Task.WhenAll(classNameTasks)));
        IResult result;
        if (classNames[0] == null)
            result = new TextResult("Error accessing api - check internet connection/api address");
        else 
            result = new TextResult("Hello dear user – we’ve selected three new class names for you, and they are " + classNames[0] + ", " + classNames[1] + ", and " + classNames[2]);
        result.display();
    }
}

Comme vous pouvez le voir, dans les deux implémentations, j'ai had pour faire la ligne result = new TextResult("Error accessing api - check internet connection/api address"); pour signaler l'erreur.

Quelle est la meilleure pratique en POO/bonne conception pour avoir un error_string Constant auquel je peux accéder dans toutes mes implémentations?

tel qu'il est actuellement, le code est dupliqué.

18
Ofek Agmon

Je ne pense pas qu'il existe une meilleure pratique. C'est juste une question de préférence.

Je stocke des constantes dans des classes statiques.

public static class Constants
{
   public static class Messages
   {
      public const string Error = "Error accessing api...";
      public const string Hello = "Hello ...";
   }
}

Usage

var result = new TextResult(Constants.Messages.Error);

FYI: Certains développeurs préfèrent Enum.

31
Win

Je fais généralement une distinction en fonction du public cible du message. En tant que tel, je les divise en deux catégories.
Quelle que soit la catégorie, j'évite d'écrire le même code plus d'une fois (par exemple, les chaînes de message).

Messages des développeurs

  • Messages affichés dans tests unitaires, messages affichés uniquement pendant débogage, ou des messages enregistrés de manière très détaillée diagnostic des dossiers
  • Les messages des développeurs nécessitent pas de localisation et doivent être écrits dans la langue de la maison de développement.
    Par exemple, si la société de développement est située à Moscou, il existe un argument solide pour écrire des messages de développeur en russe.
    Dans la pratique, de nombreux développeurs choisissent l'anglais.
  • Les options de mise en œuvre sont multiples. Je reste généralement simple, en utilisant des champs dans une classe statique. Notez que vous pouvez avoir une classe de messages pour chaque type qui affichera des messages, ou vous pouvez avoir une classe de messages centrale dans laquelle vous regroupez plusieurs classes. Vous pourriez avoir des groupes de messages imbriqués. Vous pouvez également ajouter d'autres types de constantes à utiliser dans votre code ... Comme je l'ai mentionné, les options et les préférences abondent.

    public static class FeatureMessages
    {
        #region Public Fields
    
        public const string ApiAccessError = 
            @"Error accessing api - check internet connection/api address";
        public const string SelectedClassFormatString = 
            @"Hello dear user – the selected class name is {0}";
    
        #endregion
    }
    

Messages utilisateur

  • Messages affichés aux utilisateurs finaux. Par exemple, l'installation invite, chez l'utilisateur GUI menus, sur un avertissement utilisateur boîtes de message, etc.
  • Ces messages doivent être localisés.
  • L'implémentation est simple et nécessitera au moins un fichier de ressources linguistiques par défaut. Il existe de nombreuses ressources qui peuvent vous montrer comment procéder, vous pouvez voir une explication simple ici
9
Gustavo Mori

Je recommanderais généralement d'utiliser un fichier de ressources (créé à partir des paramètres de votre projet). Vous voudrez peut-être fournir une sorte de wrapper si vous voulez rendre ce code plus testable.

4
drz

Mettez cela dans une classe statique:

internal static class ErrorMessage
{
    public const string NoAccess = "Error accessing api - check internet connection/api address";
}

Et vous pouvez faire référence à cela en utilisant:

result = new TextResult(ErrorMessage.NoAccess);

Ou, vous pouvez utiliser un fichier de ressources.

3
Xiaoy312

Non pas que je ne sois pas d'accord avec la réponse de @ Win, je pense que placer les constantes Error et Hello qui sont logiquement liées à IFeature dans une classe statique non liée pour éviter la duplication pourrait ne pas être une approche appropriée. Si l'objectif est d'éviter les doublons, je voudrais y parvenir de la manière suivante:

public abstract class Feature:IFeature
{
    public static readonly string Error = "Error accessing api...";
    public static readonly string Hello = "Hello ...{0}";

    protected IWebApi webApi;

    protected Feature(IWebApi webApi)
    {
        this.webApi = webApi;
    }
    public async Task execFeature()
    {
        var o = _execFeature();
        IResult result;
        if(o==null)
            result = new TextResult(Error);
        else 
            result = new TextResult( string.Format(Hello, o);
        result.display();
    }
    protected abstract object _execFeature();
}

Alors maintenant, j'ai atteint non seulement une minimisation optimale de la duplication de code, placez Error et Hello là où ils appartiennent logiquement. Les première et deuxième classes d'entités peuvent désormais hériter de la classe d'entités:

public class FirstFeature:Feature
{
    public FirstFeature(IWebApi webApi):base(webApi){}

    protected override object _execFeature ()
    {
        //your code for first Feature
        //return response if no error else return null
    }
}

public class SecondFeature:Feature
{
    public SecondFeature(IWebApi webApi):base(webApi){}

    protected override object _execFeature ()
    {
        //your code for second Feature
        //return class name[0] if no error else return null
    }
}

Voilà donc ce que serait mon design.

2
Mukesh Adhvaryu