È una cattiva pratica includere tutte le enumerazioni in un file e usarlo in più classi?

11

Sono un'aspirante sviluppatrice di giochi, lavoro occasionalmente su giochi indipendenti e per un po 'ho iniziato a fare qualcosa che all'inizio sembrava una cattiva pratica, ma voglio davvero ottenere una risposta da alcuni programmatori esperti qui .

Diciamo che ho un file chiamato enumList.h dove dichiaro tutte le enumerazioni che voglio usare nel mio gioco:

// enumList.h

enum materials_t { WOOD, STONE, ETC };
enum entity_t { PLAYER, MONSTER };
enum map_t { 2D, 3D };
// and so on.

// Tile.h
#include "enumList.h"
#include <vector>

class tile
{
    // stuff
};

L'idea principale è che dichiaro tutte le enumerazioni nel gioco in 1 file , e quindi importare quel file quando ho bisogno di usare un certo enum da esso, piuttosto che dichiararlo nel file dove Ho bisogno di usarlo. Lo faccio perché rende le cose pulite, posso accedere ad ogni enum in 1 posto piuttosto che avere pagine aperte esclusivamente per accedere a un enum.

Questa è una cattiva pratica e può influire in qualche modo sulle prestazioni?

    
posta Bugster 08.12.2012 - 11:33
fonte

7 risposte

31

Penso davvero che sia una cattiva pratica. Quando misuriamo la qualità del codice, c'è qualcosa che chiamiamo "granularità". La tua granularità soffre gravemente mettendo tutte quelle enumerazioni in un singolo file e quindi anche la manutenibilità soffre.

Avrei un singolo file per enum per trovarlo rapidamente e raggrupparlo con il codice comportamentale della specifica funzionalità (ad esempio enum dei materiali nella cartella in cui il comportamento del materiale è ecc.);

The main idea is that I declare all enums in the game in 1 file, and then import that file when I need to use a certain enum from it, rather than declaring it in the file where I need to use it. I do this because it makes things clean, I can access every enum in 1 place rather than having pages openned solely for accessing one enum.

Potresti pensare che sia pulito, ma in realtà non lo è. Accoppia le cose che non appartengono alla funzionalità e al modulo e diminuisce la modularità della tua applicazione. A seconda delle dimensioni del tuo codice base e della modularità con cui vuoi che il tuo codice sia strutturato, questo potrebbe trasformarsi in un problema più grande e in un codice / dipendenze non puliti in altre parti del tuo sistema. Tuttavia, se si scrive solo un piccolo sistema monolitico, questo non si applica necessariamente. Eppure, non lo farei nemmeno per un piccolo sistema monolitico.

    
risposta data 08.12.2012 - 12:29
fonte
20

Sì, è una cattiva pratica, non a causa delle prestazioni, ma a causa della manutenibilità.

Rende le cose "pulite" solo nel modo OCD "raccogli cose simili insieme". Ma in realtà non è l'utile e buono tipo di "pulizia".

Le entità di codice dovrebbero essere raggruppate per massimizzare coesione e ridurre a icona accoppiamento , che si ottiene meglio raggruppandoli in moduli funzionali ampiamente indipendenti. Raggruppandoli in base a criteri tecnici (come mettere insieme tutte le enumerazioni) si ottiene l'opposto - si accoppia codice che non ha assolutamente alcuna relazione funzionale e mette enumeri che potrebbero essere utilizzati solo in un posto in un file diverso.

    
risposta data 08.12.2012 - 12:49
fonte
7

Bene, questo è solo data (non comportamento). Il peggio che potrebbe / teoricamente accadere è che lo stesso codice sia incluso e compilato più di una volta producendo un programma relativamente più grande.

È semplicemente impossibile che tali include possano aggiungere più cicli alle tue operazioni, dato che non c'è alcun codice comportamentale / procedurale al loro interno (nessun loop, nessun ifs, ecc.).

Un programma (relativamente) più ampio può difficilmente influenzare le prestazioni (velocità di esecuzione) e, in ogni caso, è solo una remota preoccupazione teorica. La maggior parte (forse tutti) i compilatori gestiscono include in modo tale da prevenire tali problemi.

IMHO, i vantaggi che ottieni con un singolo file (codice più leggibile e più gestibile) in gran parte superano ogni possibile inconveniente.

    
risposta data 08.12.2012 - 12:04
fonte
3

Per me tutto dipende dallo scopo del tuo progetto. Se c'è un file con 10 structs e che sono gli unici mai usati, mi sentirei perfettamente a mio agio con un file .h. Se disponi di diversi tipi di funzionalità, ad esempio unità, economia, edifici, ecc., Sicuramente dividerei le cose. Crea un'unità.h dove risiedono tutte le strutture che si occupano di unità. Se vuoi fare qualcosa con unità da qualche parte devi includere units.h sure, ma è anche un bel "identificatore" che qualcosa con unità è probabilmente fatto in questo file.

Guardalo in questo modo, non comprati un supermercato perché hai bisogno di una lattina di coca;)

    
risposta data 08.12.2012 - 12:03
fonte
3

Non sono uno sviluppatore di C ++, quindi questa risposta sarà più generica per OOA & D:

Tipicamente, gli oggetti del codice dovrebbero essere raggruppati in termini di rilevanza funzionale, non necessariamente in termini di costrutti specifici della lingua. La domanda chiave, sì e no, che dovrebbe sempre essere posta è: "ci si aspetta che il coder finale utilizzi la maggior parte o tutti gli oggetti che ottengono quando consumano una libreria?" Se sì, raggruppa. In caso contrario, prendi in considerazione la suddivisione degli oggetti di codice e il loro posizionamento più vicino ad altri oggetti che ne hanno bisogno (aumentando così la possibilità che il consumatore abbia bisogno di tutto ciò che sta effettivamente accedendo).

Il concetto di base è "alta coesione"; i membri del codice (dai metodi di una classe fino alle classi in un namespace o DLL e le stesse DLL) dovrebbero essere organizzati in modo tale che un programmatore possa includere tutto ciò di cui hanno bisogno e nulla che non facciano. Ciò rende il design generale più tollerante nei confronti del cambiamento; le cose che devono cambiare possono essere, senza influenzare altri oggetti di codice che non devono cambiare. In molte circostanze, rende l'applicazione più efficiente in termini di memoria; una DLL viene caricata nella sua interezza nella memoria, indipendentemente da quante di quelle istruzioni siano mai state eseguite dal processo. La progettazione di applicazioni "snelle" richiede quindi di prestare attenzione a quanto codice viene tirato in memoria.

Questo concetto si applica a praticamente tutti i livelli di organizzazione del codice, con vari gradi di impatto su manutenibilità, efficienza della memoria, prestazioni, velocità di costruzione, ecc. Se un codificatore deve fare riferimento a un'intestazione / DLL di dimensioni piuttosto monolitiche solo per accedere un oggetto, che non dipende da nessun altro oggetto in quella DLL, probabilmente l'inclusione di quell'oggetto nella DLL dovrebbe essere ripensata. Tuttavia è possibile andare troppo lontano anche dall'altra parte; una DLL per ogni classe è una cattiva idea, perché rallenta la velocità di costruzione (più DLL da ricostruire con sovraccarico associato) e rende la versione un incubo.

Caso in questione: se un uso reale della libreria di codici implicasse l'uso della maggior parte o di tutte le enumerazioni che si stanno inserendo in questo singolo file "enumerations.h", quindi con tutti i mezzi raggrupparle; saprai dove cercare per trovarli. Ma se il tuo programmatore che consuma potrebbe aver bisogno solo di una o due delle dozzine di enumerazioni che stai fornendo nell'intestazione, allora ti incoraggio a metterle in una libreria separata e farne una dipendenza da quella più grande con il resto delle enumerazioni . Ciò consente ai coder di ottenere solo uno o due che vogliono senza collegarsi alla DLL più monolitica.

    
risposta data 10.12.2012 - 18:56
fonte
1

Questo tipo di cose diventa un problema quando più sviluppatori lavorano sullo stesso code-base.

Ho sicuramente visto file globali simili diventare un nesso per le collisioni di fusione e ogni sorta di dolore per progetti (più grandi).

Tuttavia, se sei l'unico che lavora al progetto, allora dovresti fare tutto ciò che ti è più comodo e adottare solo le "migliori pratiche" se comprendi (e concordi) la motivazione che sta dietro di esse.

È meglio fare degli errori e imparare da loro piuttosto che rischiare di rimanere bloccato con le pratiche di programmazione del culto del carico per il resto della tua vita.

    
risposta data 09.01.2014 - 18:13
fonte
0

Sì, è una cattiva pratica farlo su un grande progetto. BACIO.

Il giovane collaboratore ha ribattezzato una semplice variabile in un file .h core e 100 tecnici hanno aspettato 45 minuti per la ricostruzione di tutti i loro file, il che ha influito sulle prestazioni di tutti. ;)

Tutti i progetti iniziano in piccolo, mongolfiera nel corso degli anni, e noi maledici quelli che hanno preso scorciatoie in anticipo per la creazione di debito tecnico. Best practice, mantenere il contenuto globale .h limitato a ciò che è necessariamente globale.

    
risposta data 13.02.2014 - 22:53
fonte

Leggi altre domande sui tag