web-dev-qa-db-ja.com

使用する実装の定数文字列のベストプラクティス

インターフェースがあるとしましょう:

_public interface IFeature
{
    Task execFeature();
}
_

および2つの実装:

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

ご覧のとおり、両方の実装でI hadを実行してresult = new TextResult("Error accessing api - check internet connection/api address");行を実行し、エラーを報告します。

すべての実装でアクセスできる定数_error_string_を持つOOP/Good Designのベストプラクティスは何ですか?

現在の方法では、コードが重複しています。

18
Ofek Agmon

ベストプラクティスはないと思います。それは好みの問題です。

静的クラス内に定数を格納します。

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

使用法

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

FYI:一部の開発者はEnumを好む

31
Win

私は通常、メッセージの対象読者に基づいて区別します。そのため、これらを2つのカテゴリに分類します。
カテゴリに関係なく、同じコード(メッセージ文字列など)を複数回記述することは避けます。

開発者メッセージ

  • 単体テストに表示されるメッセージ、の間にのみ表示されるメッセージデバッグ、または、詳細な診断ファイルに記録されたメッセージ
  • 開発者メッセージにはローカライズなしが必要であり、開発会社の言語で記述する必要があります。
    たとえば、開発会社がモスクワにある場合、開発者のメッセージをロシア語で書くという強い議論があります。
    実際には、多くの開発者が英語を選択します。
  • 実装オプションは複数あります。通常は、静的クラスのフィールドを使用してシンプルにします。メッセージを表示するタイプごとにメッセージクラスを作成することも、複数のクラスをグループ化する中央メッセージクラスを作成することもできます。メッセージグループをネストすることもできます。また、コードで使用する他のタイプの定数を追加することもできます...先ほど述べたように、オプションと設定はたくさんあります。

    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
    }
    

ユーザーメッセージ

  • エンドユーザーに表示されるメッセージ。たとえば、インストールプロンプト、ユーザーGUIメニューユーザー警告メッセージボックスなど.
  • これらのメッセージローカライズする必要があります
  • 実装は簡単で、少なくともデフォルトの言語リソースファイルが必要です。これを行う方法を示すことができる多くのリソースがあります。簡単な説明を見ることができます here
9
Gustavo Mori

通常、リソースファイル(プロジェクト設定から作成)を使用することをお勧めします。このコードをよりテストしやすくしたい場合は、何らかのラッパーを提供することができます。

4
drz

それを静的クラスに入れます:

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

そして、あなたはそれを使用してそれを参照することができます:

result = new TextResult(ErrorMessage.NoAccess);

または、リソースファイルを使用できます。

3
Xiaoy312

@Winの答えに反対するわけではありませんが、重複を避けるために、無関係の静的クラスに論理的にIFeatureに関連するErrorおよびHello constを配置することは適切なアプローチではないかもしれません。目的が重複を避けることである場合、次の方法でそれを達成したいと思います。

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

そのため、コードの重複を最小限に抑えるだけでなく、ErrorとHelloを論理的に属する場所に配置しました。 1番目と2番目のフィーチャクラスは、フィーチャクラスから継承できるようになりました。

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

それが私のデザインです。

2
Mukesh Adhvaryu