I problemi con Evitare il Puffing Denominare classi con namespace

38

Ho estratto il termine smurf naming da qui (numero 21). Per salvare qualcuno che non ha familiarità con il problema, la denominazione Smurf è l'atto di prefisso a un gruppo di classi correlate, variabili, ecc. Con un prefisso comune così si finisce con "un SmurfAccountView passa un SmurfAccountDTO a SmurfAccountController ", ecc.

La soluzione che ho sentito in generale è di creare uno spazio dei nomi smurf e rilasciare i prefissi smurf. Questo in genere mi è servito bene, ma sto incontrando due problemi.

  1. Sto lavorando con una libreria con una classe Configuration . Potrebbe essere stato chiamato WartmongerConfiguration ma è nello spazio dei nomi Wartmonger, quindi è chiamato Configuration . Anch'io ho una classe Configuration che potrebbe essere chiamata SmurfConfiguration , ma è nello spazio dei nomi Smurf in modo che sia ridondante. Ci sono dei posti nel mio codice in cui Smurf.Configuration appare accanto a Wartmonger.Configuration e la digitazione di nomi completi è goffa e rende il codice meno leggibile. Sarebbe più carino gestire un SmurfConfiguration e (se fosse il mio codice e non una libreria) WartmongerConfiguration .

  2. Ho una classe chiamata Service nel mio spazio dei nomi Smurf che avrebbe potuto essere chiamata SmurfService . Service è una facciata in cima a una libreria Smurf complessa che esegue lavori Smurf. SmurfService sembra un nome migliore perché Service senza il prefisso Smurf è così incredibilmente generico. Posso accettare che SmurfService era già un nome generico e inutile e portare via lo smurf ha semplicemente reso questo più evidente. Ma potrebbe essere stato chiamato Runner , Launcher , ecc. E sarebbe ancora "mi sento meglio" come SmurfLauncher perché non so cosa faccia un Launcher , ma so cosa SmurfLauncher lo fa. Potresti obiettare che ciò che un Smurf.Launcher dovrebbe essere altrettanto evidente di Smurf.SmurfLauncher , ma potrei vedere 'Smurf.Launcher essere una sorta di classe correlata all'impostazione piuttosto che una classe che lancia smurfs.

Se esiste un modo aperto e chiuso per gestire uno di questi, sarebbe fantastico. In caso contrario, quali sono alcune pratiche comuni per mitigare il loro fastidio?

    
posta Daniel Koverman 25.03.2013 - 23:53
fonte

5 risposte

16

Ottieni alcuni punti positivi.

  1. Per quanto riguarda l'avere classi duplicate, puoi creare alias classi in C #. Utilizza ad esempio using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme; Vedi questo post su StackOverflow . Non hai indicato il tuo linguaggio di programmazione ma l'ho dedotto da ciò che hai scritto. Quindi, quando hai a che fare con due diversi progetti, puoi renderli alias come SmurfConfiguration e WartmongerConfiguration che libererebbero ambiguità quando consumano entrambe le classi.

  2. Poiché un servizio è esposto ad applicazioni esterne, non vedo alcun problema nel branding del servizio con il nome dell'applicazione, quindi in questo caso SmurfService sarebbe valido poiché in realtà disambiguerebbe i gruppi di servizi nel applicazione che consuma.

Ritengo che gli spazi dei nomi dovrebbero essere usati per evitare questo stile di denominazione. Rende più difficile il grok del codice e viene visualizzato il valore nominale di una classe senza leggere MyCompanyMyProductMyAreaClassName. L'utilizzo della tecnica di aliasing consente di ridurre l'ambiguità laddove necessario. L'unica volta in cui penso che dovresti introdurre complessità nella tua denominazione è, come ho sottolineato al n. 2, quando le persone consumano un servizio. È qui che ha perfettamente senso avere questo stile di denominazione perché se il consumatore ha una varietà di servizi che sta consumando, l'ambiguità potrebbe confondere.

    
risposta data 26.03.2013 - 00:05
fonte
25

Il punto dello spazio dei nomi è così che puoi avere classi con lo stesso nome da librerie diverse senza che si scontrino. Quando è necessario utilizzare la stessa classe con nome da entrambi, è necessario rimuovere l'ambiguità prefiggendo uno o entrambi con il suo ambito di spazio dei nomi.

Detto questo, non è poi così male avere un branco di classi di Smurf se Smurf ti dice qualcosa di specifico sulla classe. I nomi delle classi dovrebbero essere abbastanza descrittivi da darti qualche informazione su cosa fa la classe.

      Session
       ^   ^
      /     \
DBSession   HttpSession

Allo stesso modo DBSession potrebbe prendere un oggetto DBRequest che restituisce un oggetto DBResponse . HttpSession potrebbe anche operare su HttpRequest e HttpResponse oggetti.

Queste sono classi di Smurf con uno scopo.

Potrebbero vivere nello spazio dei nomi MyCompany ma MyCompanyHttpSession e MyCompanyDBSession non ti forniscono più informazioni di quante ne avevi prima. In questo caso rilascia il Puffo e crea uno spazio dei nomi.

MyCompany.HttpSession
    
risposta data 26.03.2013 - 17:26
fonte
2

È sicuramente una buona regola pratica che se hai un prefisso comune su un gruppo di classi, allora probabilmente meritano di andare nel loro spazio dei nomi. Per affrontare il problema, quindi, quando è necessario utilizzare classi con nomi simili da due spazi dei nomi:

1) Alias lo spazio dei nomi, anche se lo renderei breve e al punto, qualsiasi     abbreviazione naturale, forse anche solo 1 lettera:

using Sm = Smurf;
using W = Wartmonger;

Quindi, anteponi sempre il prefisso e le istanze del nome in modo appropriato:

Sm::Configuration smConf; 
W::Configuration wConf;

2) Alias la classe, come suggerito in un'altra risposta.

using SmConf = Smurf.Configuration;

3) Qualsiasi libreria su cui hai il controllo, considera di non usare il termine "Configurazione". Utilizza il thesaurus: ad es. "Impostazioni", "Modello", "Parametri". Potrebbe comunque essere più significativo per il contesto: E.g. se Smurf fosse una sorta di modulo di analisi numerica che avresti scritto forse "Parametri" sarebbe meglio per la sua configurazione. Usa il particolare vocabolario associato al contesto di un modulo a tuo vantaggio per trovare nomi univoci che mantengano l'unicità anche se mescolati in altri spazi dei nomi. Ritengo che questo potrebbe essere una specie di risposta alla domanda OP 2

4) Codice del refactoring in modo da non dover mescolare l'uso della configurazione da due posti diversi. I dettagli dipendono da te.

5) Combina le due configurazioni in una prima di passarla alla tua classe. Usa una classe conf conf per rappresentare:

struct Conf {
    SmurfConfiguration smurf;
    WartmongerConfiguation wart;
}

I nomi delle variabili dei membri brevi ora hanno lo stesso effetto di aliasing della classe / spazio dei nomi.

    
risposta data 26.03.2013 - 14:14
fonte
2

Mi sono imbattuto in questo stesso punto di confusione e di solito è davvero una questione di includere il tipo di cosa che fa parte del suo nome.

Hai menzionato SmurfConfiguration e WartmongerConfiguration come potenziali tipi di configurazioni. Indica di aver rimosso l'aggettivo (il suo genere) nel suo spazio dei nomi, in modo che quello che ti rimane sia solo la percentuale di vaniglia% co_de. Eviterei di farlo.

È come decidere che il gelato alla fragola è solo gelato nel namespace delle fragole e allo stesso modo con il cioccolato, ma quello che è successo è che hai divorziato dall'aggettivo che gli dà la sua identità dalla cosa stessa. Non è gelato nella categoria fragola. È gelato alla fragola - una specie di gelato.

Immaginiamo che nella tua app importi la classe Configuration e poi inizi a creare un'istanza direttamente da Strawberry.IceCream .

var ic = new IceCream(); //actually I'm strawberry ice cream

Questo può sembrare buono e buono, fino al momento in cui finisci per importare un'altra classe IceCream . Ora sei tornato al problema originale di dover in qualche modo distinguere tra loro, che è problematico. Quello che volevi da sempre era:

var sic = new StrawberryIceCream();
var cic = new ChocolateIceCream();

I namespace sono meglio lasciati per evitare potenziali conflitti tra terze parti che potrebbero incidentalmente rappresentare gli stessi concetti nelle loro librerie. Quando uno sviluppatore crea una libreria o un progetto, tuttavia, dovrebbe nominare ciascun concetto in modo univoco e utilizzare gli spazi dei nomi come cartelle solo per l'organizzazione. Spesso il nome della cartella si trova nel nome dei concetti che organizza e va bene.

    
risposta data 05.08.2014 - 14:59
fonte
0

Sembra strano aggiungere un punto al nome che ti infastidisce.

Wartmonger.Configuration configuration = Wartmonger.Configuration .new();

// vs

WartmongerConfiguration configuration = WartmongerConfiguration.new();

Se entrambe le configurazioni Smurf e Wartmonger vengono utilizzate insieme in un unico posto, ma in modo separato vengono utilizzate in più posizioni, allora lo spazio dei nomi è sicuramente un buon approccio.

Avere namespace darà la possibilità di usare nomi "puliti" nel codice interno, dove con prefissi si finisce usando SmurfConfiguration all'interno del codice interno di SmurfService , che può diventare fastidioso ogni volta che si apre quel codice.

    
risposta data 02.02.2018 - 20:33
fonte

Leggi altre domande sui tag