インターフェースがあるとしましょう:
_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のベストプラクティスは何ですか?
現在の方法では、コードが重複しています。
ベストプラクティスはないと思います。それは好みの問題です。
静的クラス内に定数を格納します。
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を好む
私は通常、メッセージの対象読者に基づいて区別します。そのため、これらを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
}
ユーザーメッセージ
通常、リソースファイル(プロジェクト設定から作成)を使用することをお勧めします。このコードをよりテストしやすくしたい場合は、何らかのラッパーを提供することができます。
それを静的クラスに入れます:
internal static class ErrorMessage
{
public const string NoAccess = "Error accessing api - check internet connection/api address";
}
そして、あなたはそれを使用してそれを参照することができます:
result = new TextResult(ErrorMessage.NoAccess);
または、リソースファイルを使用できます。
@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
}
}
それが私のデザインです。