Dove si trova il posto appropriato per gli oggetti funzione?

1

Ho un set di tipi che possono essere personalizzati dai formattatori. Un formattatore è un oggetto funzione definito come Func<string, string, string> . Il client di una libreria può scegliere di implementare FormattedLoggerBase con uno dei formattatori forniti o scriverne uno nuovo.

public abstract class FormattedLoggerBase : LoggerBase
    {
        public Func<string, string, string> Formatter { get; set; }    

        /.../
    }

Dove è il posto migliore dove mettere tutti gli oggetti funzione?

  • Una classe statica?
  • Classi wrapper che implementano IFormatter?
  • Factory?

La classe statica ha un overhead minimo, ma le classi wrapper fornirebbero un messaggio chiaro agli utenti, che può essere iniettato da formattatore. D'altra parte, forniscono molto spazio sul codice, oltre che in fabbrica. Quale sceglieresti e perché? O forse hai una soluzione migliore?

    
posta Piotr Falkowski 18.02.2018 - 14:51
fonte

2 risposte

3

Questa è in realtà solo la scelta del rivenditore (a prescindere dagli standard di codifica delle aziende o da un lead di sviluppo che ha deciso come affrontarlo, a quel punto la domanda diventa un po 'discutibile).

Mi piacciono di più le classi statiche, poiché l'uso di classi statiche nidificate consente di utilizzare essenzialmente "cartelle dello spazio dei nomi". Non so se c'è un nome appropriato per questo, è quello che io chiamo (e sto traducendo liberamente dall'olandese).

Ad esempio:

public static class Formatters
{
    public static class Date
    {
        public static Func<DateTime, string> UtcFormat = ...;
        public static Func<DateTime, string> IsoFormat = ...;
    }

    public static class PhoneNumber
    {
        public static Func<string, string> InternationalFormat = ...;
        public static Func<string, string> NationalFormat = ...;
        public static Func<string, string> InternalFormat = ...;
    }
}

Nota: ho rimosso il secondo parametro stringa, poiché sospetto che la suddivisione nell'esempio già selezioni la formattazione per la quale il tuo secondo parametro avrebbe probabilmente dovuto essere utilizzato.

Questo ti dà una bella funzionalità di autocomplete sul tuo intellisense, che apprezzo molto se c'è una grande quantità di formattatori.

Ho anche usato approcci simili per es. impostazioni globali di configurazione. Mi piace avere la possibilità di ordinare una grande lista di opzioni con un impatto minimo sul codice di base (le classi nidificate non sporcano davvero il resto della tua base di codice).

    
risposta data 20.02.2018 - 12:02
fonte
0

Esistono molti usi simili di classi statiche là fuori per implementazioni predefinite. qualcosa come:

myLogger.Formatter = LoggerNamespace.DefaultFormatters.UkDate;

non sarebbe inusuale.

Personalmente la mia opinione è quando hai interfacce e hai digitato delegati perché non li usi?

public interface IFormatter
{
    string Format(string in, string format);
}

o

public delegate string Formatter(string in, string format);

Se hai una classe o una funzione che implementa uno di questi, il suo contenuto, classe di spazio dei nomi o progetto è meno importante, in quanto il suo uso è chiaramente indicato dal tipo.

Il lato negativo di una statica sarebbe se fosse referenziato direttamente da qualche parte

myLogger.WriteLog(string msg)
{
     //now i cant test :(
     this.write(LoggerNamespace.DefaultFormatters.UkDate(msg,""));
}

Mentre puoi evitarlo prestando attenzione, non puoi impedire che ciò accada nel codice di altri popoli

    
risposta data 18.02.2018 - 16:02
fonte

Leggi altre domande sui tag