Implementazione di un livello di servizio con una classe statica

4

Ho strutturato i miei livelli di "servizio" (o, quello che pensavo fosse una funzionalità simile al servizio) come classi statiche in cui ogni classe è un raggruppamento di funzioni complementari che insieme forniscono un insieme coerente di operazioni per supportare i bisogni dei livelli di consumo .

public static class ElementService
{
    public static Element GetElementByAtomicNumber(int atomic_number)
    {
        ElementRepositorySQL elementRepositorySql = new ElementRepositorySQL();

        return elementRepositorySql.Read(atomic_number);
    }
}

Ad esempio, i controllori usano il livello di servizio per leggere / scrivere su un repository invece di gestirlo direttamente.

public class ElementController
{
    public ElementModel Model {get; set;}

    public void LoadModel(int atomic_number)
    {
        Model = new ElementModel();

        Element e = ElementService.GetElementByAtomicNumber(atomic_number);

        Model.Name = e.Name.ToUpper();
        Model.Weight = Math.Round(e.AtomicWeight,4).ToString();
    }
}

10 Golden Rules Of Good OOP , la regola # 5 afferma:

  1. Avoid Static Classes for Helpers, Utilities & C

Unfortunately, static classes act frequently as a global state and create the non-determinism that should be avoided. But it gets worse. Since static classes can be used everywhere in the code without being passed explicitly as parameters, they create secret dependencies that are not revealed by the API documentation.

Non vedo come questo sarebbe un grosso problema se le chiamate al servizio sono fatte rigorosamente all'interno del livello per cui sono state progettate? Ho una convenzione in cui solo i controller chiamano il servizio strato; quel particolare insieme di servizi supporta i controller.

Last, but not least, code using static classes is not testable in isolation, making unit testing a nightmare.

Unless strictly needed for performance reasons, the use of static classes should be avoided. Static variables are still OK for constant objects (although a static property without setter would be better) or to hold private references to objects inside factory classes.

La maggior parte delle funzionalità fornite da questi servizi è così semplice che credo che il testing delle unità sarebbe semplicemente eccessivo (record di lettura / scrittura di id).

Considerando queste circostanze, varrebbe ancora la pena di refactoring dell'implementazione della classe statica? È una buona porzione di codice, quindi avrei bisogno di un RoI comparabile.

    
posta samis 07.04.2017 - 22:34
fonte

3 risposte

6

The majority of the functionality these services provide is so straight forward I think unit testing would just be overkill (read/write record by id).

Certo, ma non è questo il problema. Il problema è se sei in grado di isolare la dipendenza sul livello di servizio quando l'unità testa il livello immediatamente sopra, ad es. il tuo codice%. Se non ci riesci, allora tutti i tuoi test unitari richiederanno un database per essere eseguiti, e non sarai in grado di dire se i test falliti sono dovuti a un difetto nel controller o a un difetto in alcuni livelli più in basso lo stack di servizi, inclusi dati non corretti nel database stesso.

    
risposta data 07.04.2017 - 22:43
fonte
3

Il motivo per cui abbiamo queste "regole d'oro" e principi come YAGNI e SOLID è perché riassumono le cose in cui l'argomento per / contro è complicato ma il principio generale manterrà fuori dai guai il programmatore inesperto.

Nel caso di "Non usare static" ovviamente non è sempre sbagliato a usarlo o forse puoi ignorare gli svantaggi per convenienza. Ma se non capisci PERCHÉ la regola è lì allora il miglior consiglio è seguirlo.

A mio avviso, la ragione predominante per questa regola è dovuta a OOP. gli sviluppatori iniziarono a scrivere codice OOP, scoprendo di non avere riferimenti a un'istanza di un oggetto con un metodo generale che volevano chiamare e risolvere il problema rendendo il metodo statico.

Sebbene questo risolva il problema immediato, non è OOP. Gli studenti chiedono "ma perché non è OOP?" e la risposta semplice, 'perché hai statici' è data. Da qui la regola.

Nel tuo caso particolare però, lo svantaggio pratico (tra gli altri) di rendere statico il tuo livello di servizio è che non puoi prenderlo in giro e testare i tuoi controller (il livello di hosting lo chiamerei)

Ad esempio, personalmente, creo normalmente un livello di servizio Mock che restituisce risultati da file statici, lo inserisco nei miei web API / controller e utilizzo il sito risultante nei test di integrazione dei componenti che hanno consumato l'API.

Questo non è possibile con un livello di servizio statico in quanto non è possibile compilare i controller senza l'implementazione statica e reale del livello di servizio.

    
risposta data 08.04.2017 - 06:42
fonte
1

La parte di codice che contiene o utilizza classi / metodi statici non è OOP. Non beneficerai di nessuno dei vantaggi OOP. Usare OOP o no è solo la tua decisione, ma prima di prendere quella decisione dovresti capire cosa stai perdendo comprendendo bene cosa significa OOP.

Se già lo sai, allora prendi una decisione mettendo in equilibrio ciò che perdi e ciò che guadagni (codice più semplice, tempo, ecc.)

Se non lo sai, leggi di più qui:

risposta data 08.04.2017 - 04:50
fonte

Leggi altre domande sui tag