Лучшая практика для постоянной строки для использования в реализациях
Скажем, у меня есть интерфейс:
public interface IFeature
{
Task execFeature();
}
и две реализации:
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();
}
}
Как вы можете видеть, в обеих реализациях я имел, чтобы сделать строку result = new TextResult("Error accessing api - check internet connection/api address");
, чтобы сообщить об ошибке.
Какова наилучшая практика в OOP/Good Design, чтобы иметь постоянный error_string
, который я могу получить во всех своих реализациях?
как сейчас, код дублируется.
Ответы
Ответ 1
Я не думаю, что есть лучшая практика. Это просто вопрос предпочтения.
Я храню константы внутри статических классов.
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
}
Сообщения пользователя
- Сообщения, отображаемые конечным пользователям. Например, установите подсказки в пользовательских меню GUI, в сообщениях предупреждений пользователя и т.д.
- Эти сообщения должны быть локализованы.
- Реализация прост и потребует, по крайней мере, файла языковых ресурсов по умолчанию. Есть много ресурсов, которые могут показать вам, как это сделать, вы можете увидеть простое объяснение здесь
Ответ 3
Обычно я рекомендую использовать файл ресурсов (созданный из ваших настроек проекта). Возможно, вы захотите предоставить какую-то оболочку, если хотите сделать этот код более пригодным для тестирования.
Ответ 4
Поместите это в статический класс:
internal static class ErrorMessage
{
public const string NoAccess = "Error accessing api - check internet connection/api address";
}
И вы можете ссылаться на это, используя:
result = new TextResult(ErrorMessage.NoAccess);
Или вы можете использовать файл ресурсов.
Ответ 5
Не то, чтобы я не соглашался с ответом @Win, я считаю, что помехи Error и Hello consts, которые логически связаны с IFeature в несвязанном статическом классе во избежание дублирования, могут быть не подходящим подходом. Если цель состоит в том, чтобы избежать дублирования, я хотел бы достичь ее следующим образом:
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, где они логически принадлежат. Первый и второй классы классов теперь могут наследоваться от класса Feature:
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
}
}
Так что мой дизайн будет.
Ответ 6
Помимо того, что ваша функция отображает сообщения, которые, как я думаю, не должны делать, у вас явно есть проблема с локализацией, если вы помещаете сообщения в свой код. Независимо от того, где вы держите его и как вы обращаетесь к нему, вы не хотите перекомпилировать, чтобы иметь другой язык. Возможно, вы даже не захотите перекомпилировать, чтобы исправить глупую орфографическую ошибку.
В вашем коде используйте коды ошибок. Это может быть, например, перечисление. Затем в вашем приложении переднего плана есть услуга переводчика (для этого .NET имеет довольно приятную функцию, называемую "ресурсы" ).
Таким образом, у вас могут быть разные ресурсы для разных интерфейсов (например, для французского языка, или, возможно, для детей с более простым языком или для тех, кто может справиться с реальной сделкой).
Кроме того, у вас также может быть автоматическая передняя часть, которая может реагировать на коды вместо того, чтобы анализировать сообщения об ошибках и бросать подгонку, когда кто-то исправляет орфографическую ошибку или находит более благоприятный термин для чего-то.