I metodi Extensions dovrebbero essere utilizzati per la logica aziendale

6

In C # abbiamo Extension methods .

Extension methods enable you to add methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.

An extension method is a special kind of static method, but they are called as if they were instance methods on the extended type.

Tuttavia, in uno dei nostri momenti di progettazione minori, abbiamo iniziato a sostituire le classi concrete che contengono la logica aziendale e le spostiamo in Extension Methods .

All'inizio i vantaggi sembravano puliti, ad esempio potremmo sostituire qualcosa di simile (esempio molto semplificato).

var AddressUtils = new AddressUtils();
AddressUtils.CleanAddress(order);

var ValidationUtils = new ValidationUtils();
ValidationUtils.ValidateCustomer(Order);

con

Order.CleanAddress();
Order.ValidateCustomer();

Ie stavamo sostituendo un sacco di classi istanziabili stateless con metodi statici a mano corta (zucchero sintattico) che rendevano il codice più leggibile. Questo non mi è mai piaciuto molto.

Ora abbiamo un sacco di classi statiche con metodi vari, la maggior parte non sono nemmeno generiche o basate su interfacce. I.e uso singolo.

Aggiungendo a questo c'è una nozione comune che le classi statiche non sono adatte allo sviluppo basato su test.

Quindi le alternative sono davvero

  • Torna a lezioni di helper in stile util concrete
  • E / o incapsula la logica in una sorta di servizio DI
  • Oppure aggiungi la logica al modello stesso.
  • O con la logica riutilizzabile sparsa sui vari servizi che devono essere utilizzati.

Per quanto riguarda la seconda opzione, l'ordine (come la maggior parte dei modelli) sono in realtà entità di dati, (e ancora una volta) non sembra giusto (o persino fattibile) spingere la logica di business verso il dominio modelli

Quindi mi mancano le classi helper (a meno che non ci siano modelli migliori), i metodi di estensione, i servizi DI, una sorta di logica basata sull'entità o un imprevedibile fabbrica di spaghetti.

    
posta TheGeneral 23.01.2018 - 05:03
fonte

2 risposte

4

Hai citato

Extension methods enable you to add methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.

e questo è il momento in cui dovresti usarli quasi esclusivamente - dove hai un caso in cui avrebbe senso estendere un tipo con quel metodo, ma non puoi farlo, né creando un nuovo tipo derivato, né mediante la ricompilazione, né con qualsiasi altro mezzo che modifichi il tipo originale.

Lo scenario tipico per questo è: il tipo è sigillato, e non è sotto il tuo controllo - forse una libreria di terze parti - o vuoi evitare di aggiungere un metodo che richiede una dipendenza aggiuntiva che non deve essere aggiunta al assemblaggio in cui è definito il tipo.

Quindi la prima cosa da verificare qui è se questi vincoli si applicano, e se no, il posto preferito per mettere un metodo addizionale dovrebbe essere la classe stessa. Se il codice non può essere modificato, ma la classe non è sigillata, si potrebbe prendere in considerazione l'uso di una sottoclasse invece di un metodo di estensione. In questa situazione, preferirei metodi di estensione su sottoclassi a meno che non sia necessario l'accesso ai membri protetti. In questa situazione non vi è alcun beneficio nell'uso della sottoclasse, né nella testabilità né nell'organizzazione del codice.

Informazioni sulla testabilità: i metodi di estensione non sono in alcun modo più semplici o più difficili da eseguire con il test unitario rispetto a qualsiasi altro metodo statico o non statico. La testabilità o TDD diventa solo una preoccupazione quando altro codice che si basa su tale metodo deve essere testato separatamente. Quindi, se ti imbatti in una situazione in cui devi "deridere" il metodo di estensione stesso, è il momento di ridefinire il metodo in una classe di utilità che può essere sostituita più facilmente da una simulazione a scopo di test.

Quindi l'uso dei metodi di estensione va bene, se tu

  • avere un metodo che si adatta chiaramente (!) all'area di responsabilità del tipo che vuoi estendere

  • non può modificare facilmente il tipo stesso

  • non puoi o non vuoi usare l'ereditarietà

  • non hanno il requisito di prendere in giro la funzione nel codice che si basa su di essa.

Nota in realtà non vi è alcun motivo per cui non è possibile iniziare con un metodo di estensione, e quando si nota che si verificano le sue restrizioni, refactoring il codice. Quindi, non pensarci troppo. Nota anche che questo non ha molto a che fare con il codice business logic o il codice UI o il codice dell'infrastruttura - quando un programma è abbastanza grande, ognuno di questi "strati" può essere costituito da diversi sublayer e componenti, che possono causare una situazione in cui un " è richiesta l'estensione del tipo "transfrontaliero.

    
risposta data 23.01.2018 - 06:06
fonte
3

Adding to this there is this common notional that static classes are not a good fit for test driven development.

Questo vale solo se quei metodi statici accedono o mutano lo stato esterno. Se,

Order.CleanAddress();

modifica solo Order e non ad es. le regole di accesso tramite un servizio statico, quindi non è un disadattato per quanto riguarda il test.

Quindi, se la tua unica ragione per considerare una modifica è a scopo di test e se i tuoi metodi si comportano bene, lascia il codice così com'è.

    
risposta data 23.01.2018 - 09:18
fonte

Leggi altre domande sui tag