patterns pattern book c# string oop design-patterns interface

c# - pattern - Las mejores prácticas para cadenas constantes para que las implementaciones usen



factory pattern c# (7)

Digamos que tengo una interfaz:

public interface IFeature { Task execFeature(); }

y dos implementaciones:

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

Como puede ver, en ambas implementaciones tuve que hacer el result = new TextResult("Error accessing api - check internet connection/api address"); línea para reportar el error.

¿Cuál es la mejor práctica en OOP / Good Design para tener una error_string constante a la que puedo acceder en todas mis implementaciones?

tal como está ahora, el código está duplicado.


Aparte del hecho de que su función está mostrando mensajes, lo que creo que no debería hacer, claramente tiene un problema con la localización si coloca mensajes en su código. No importa dónde lo tenga y cómo lo acceda, no quiere volver a compilar para tener un idioma diferente. Es posible que ni siquiera desee volver a compilar para corregir un error de ortografía estúpido.

En su código, utilice códigos de error. Esto puede ser, por ejemplo, enumeraciones. Luego, en su aplicación de front-end, tenga un servicio de traductor (.NET tiene una característica muy buena llamada "recursos" para esto).

De esta manera, puede tener diferentes recursos para diferentes front-end (como uno para francés. O quizás uno para niños con un lenguaje más fácil. O uno para gente técnica que puede manejar el trato real).

Además, también puede tener un extremo frontal automatizado que puede reaccionar a los códigos en lugar de tener que analizar los mensajes de error y lanzar un ajuste cada vez que alguien corrige un error ortográfico o encuentra un término más amigable para algo.


Aquí un código.

namespace myNS { class MyClass { private readonly static string MyKey = "MyKey"; //MyCode } }


Generalmente recomendaría usar un archivo de recursos (creado a partir de la configuración de su proyecto). Es posible que desee proporcionar algún tipo de envoltorio si desea que este código sea más comprobable.


No creo que haya una mejor práctica. Es solo una cuestión de preferencia.

Almaceno constantes dentro de clases estáticas.

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

Uso

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

FYI: Algunos desarrolladores prefieren Enum.


No es que no esté de acuerdo con la respuesta de @ Win, creo que poner Error y Hello consts que están lógicamente relacionados con IFeature en una clase estática no relacionada para evitar la duplicación podría no ser un enfoque apropiado. Si el objetivo es evitar la duplicación, me gustaría lograrlo de la siguiente manera:

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

Así que ahora no solo he logrado una minimización óptima de la duplicación de código, pongo Error y Hola a donde pertenecen lógicamente. La primera y la segunda clase de entidad ahora pueden heredar de la clase de entidad:

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

Así que ese sería mi diseño.


Ponga eso en una clase estática:

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

Y puedes referenciarlo usando:

result = new TextResult(ErrorMessage.NoAccess);

O bien, puede utilizar un archivo de recursos.


Por lo general, hago una distinción basada en la audiencia deseada para el mensaje. Como tal, los divido en dos categorías.
Independientemente de la categoría, evito escribir el mismo código más de una vez (por ejemplo, cadenas de mensajes).

Mensajes del desarrollador

  • Mensajes mostrados en pruebas unitarias , mensajes que se muestran solo durante la depuración o mensajes registrados en archivos de diagnóstico súper detallados
  • Los mensajes del desarrollador no requieren localización y deben estar escritos en el idioma de la casa de desarrollo.
    Por ejemplo, si la compañía de desarrollo está ubicada en Moscú, entonces hay un fuerte argumento para escribir mensajes de desarrollador en ruso.
    En la práctica, muchos desarrolladores eligen el inglés.
  • Las opciones de implementación son múltiples. Normalmente lo hago simple, usando campos en una clase estática. Tenga en cuenta que podría tener una clase de mensaje para cada tipo que muestre mensajes, o podría tener una clase de mensaje central donde agrupe varias clases. Podrías haber anidado grupos de mensajes. También puede agregar otros tipos de constantes para usar en su código ... Como mencioné, las opciones y preferencias abundan.

    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 }

Mensajes de usuario

  • Mensajes mostrados a los usuarios finales. Por ejemplo, indicaciones de instalación, en los menús de la GUI del usuario, en los cuadros de mensajes de advertencia de un usuario , etc.
  • Estos mensajes deben ser localizados .
  • La implementación es simple y requerirá al menos un archivo de recursos de idioma predeterminado. Hay muchos recursos que pueden mostrarle cómo hacer esto, puede ver una explicación simple here