Attualmente sto scrivendo un programma più grande in C ++ e ho raggiunto un punto in cui ho avuto problemi con l'organizzazione. Mi chiedo se gli spazi dei nomi siano una via d'uscita.
Cercherò di spiegare cosa fa il programma e mostrerò un esempio semplificato del casino in cui mi trovo.
Una parte del programma configura i cosiddetti dispositivi. Ogni dispositivo deve essere configurato in modo diverso.
Quindi in pratica viene fatto quanto segue:
-
Leggi in dispositivi esistenti. I dispositivi di lettura devono essere analizzati per determinare quale tipo di dispositivo sono. Il
class Devices
fa questo. Ordina i dispositivi nei tipiDevice_type10_valve
Device_type20_drive
e così via ... -
Da un'altra fonte ottengo dati grezzi che devono essere analizzati e raccolti nel giusto tipo di dispositivo. Gestisco tutto questo in
class Devices_config_data_collection
. -
Perché non li configuro direttamente nei dispositivi? Perché ho bisogno di raccogliere più di questi input di dati insieme poiché possono avere dipendenze tra loro (ad esempio due contenitori di
Device_config_data_type10_valve
vengono uniti in unDevice_config_data_type10_valve
). -
I dati di
Devices_config_data_collection
vengono aggiunti aDevices
-
I dispositivi con i dati configurati vengono scritti all'origine con i dati configurati.
Per raggiungere questo obiettivo ho la seguente gerarchia di classi nel codice pseudo C ++
namespace Application_name { // for all the methods in the program
//Device_config_data_type_base.h // Device_config_data_type_base.cpp
class Device_config_data_type_base {
//..
};
//Device_config_data_type10_valve.h // Device_config_data_type10_valve.cpp
class Device_config_data_type10_valve : public Device_config_data_type_base {
//...
};
//Device_config_data_type20_drive.h // Device_config_data_type20_drive_valve.cpp
class Device_config_data_type20_drive : public Device_config_data_type_base {
//...
};
//.... more derived classes like this from Device_config_data_base
// Devices_data_collection.h // Devices_data_collection.cpp
class Devices_config_data_collection {
public:
// put in raw data and make a collection of config data
private:
struct data {
std::vector<Device_config_data_type10_valve> type10;
std::vector<Device_config_data_type20_drive> type20;
//... and more
};
// more stuff also sorts in valid and invalid inputs
};
// Devices_type_base.h // Devices_type_base.cpp
class Device_type_base {
//..
};
// Device_type10_valve.h // Device_type10_valve.cpp
class Device_type10_valve : public Device_type_base {
//..
void insert_config_data(const Device_config_data_type10_valve& data);
private:
// part of the private data is the config data
Device_config_data_type10_valve config_data;
};
// Device_type20_drive.h // Device_type20_drive.cpp
class Device_type20_drive : public Device_type_base {
//..
void insert_config_data(const Device_config_data_type20_drive& data);
private:
Device_config_data_type20_drive config_data;
};
//.... more derived classes like this
// Devices.h // Devices.cpp
class Devices {
public:
// Reads in existing Devices from a source
// providing a function to add the data collection to existing Devices
// writing out the configured devices back to the source
void add_data(const Devices_config_data_collection& collection);
private:
struct data {
std::vector<Device_type10_valve> type10;
std::vector<Device_type20_drive> type20;
//... and more
};
};
// a lot more parts of the programm with similiar complexity but they are not devices
}
Di solito metto ogni classe nel suo h-file e cpp-file con il nome come il nome della classe. Il problema che ho con questo è che la classe e i nomi dei file diventano molto lunghi e questo non rende il codice molto piacevole da leggere.
Quindi stavo pensando di aggiungere sotto namespace. Uno per tutti i dispositivi per isolare questa parte dal resto del programma. Ci sono più parti che non hanno nulla a che fare con i dispositivi. E un altro per le classi di dati. Quindi potrei abbreviare i nomi delle classi.
Che assomiglia a questo nel codice pseudo C ++:
namespace Application_name { // for all the methods in the program
namespace Device {
namespace Config_data {
//Device_config_data_type_base.h // Device_config_data_type_base.cpp
class Type_base {
//..
};
//Device_config_data_type10_valve.h // Device_config_data_type10_valve.cpp
class Type10_valve : public Type_base {
//...
};
//Device_config_data_type20_drive.h // Device_config_data_type20_drive_valve.cpp
class Type20_drive : public Type_base {
//...
};
//.... more derived classes like this from Device_config_data_base
}
// Devices_data_collection.h // Devices_data_collection.cpp
class Collection {
public:
// put in raw data and make a collection of config data
private:
struct data {
std::vector<Config_data::Type10_valve> type10;
std::vector<Config_data::Type20_drive> type20;
//... and more
};
// more stuff also sorts in valid and invalid inputs
};
// Devices_type_base.h // Devices_type_base.cpp
class Type_base {
//..
};
// Device_type10_valve.h // Device_type10_valve.cpp
class Type10_valve : public Type_base {
//..
void insert_config_data(const Config_data::Type10_valve& data);
private:
// part of the private data is the config data
Config_data::Type10_valve config_data;
};
// Device_type20_drive.h // Device_type20_drive.cpp
class Type20_drive : public Type_base {
//..
void insert_config_data(const Config_data::Type20_drive& data);
private:
Config_data::Type20_drive config_data;
};
//.... more derived classes like this
}
// Devices.h // Devices.cpp
class Devices {
public:
// Reads in existing Devices from a source
// providing a function to add the data collection to existing Devices
// writing out the configured devices back to the source
void add_data(const Devices_config_data_collection& collection);
private:
struct data {
std::vector<Device_type10_valve> type10;
std::vector<Device_type20_drive> type20;
//... and more
};
};
// a lot more parts of the program with similar complexity but they are not devices
}
Nota ora ho una classe Devices::type10_valve
e Devices::Config_data::type10_valve
.
Mi chiedo se questa è una buona pratica? Inoltre ora arriva il problema con i file cpp e h. Come gestirli ora per rappresentare i nomi delle classi? Se li accorro, ho un conflitto di nomi con Devices::type10_valve
e 'Devices :: Config_data :: type10_valve perché sono entrambi type10_valve.cpp / h.
È una buona pratica metterli in sottocartelle sul disco rigido e anche fare riferimento alle cartelle negli include?
Per favore fatemi sapere cosa ne pensate, quali sono le vostre esperienze.
Nota Sto usando Visual Studio 2017. Qualsiasi suggerimento per l'organizzazione di problemi come questo in particolare per questo è anche benvenuto
Se hai bisogno di maggiori dettagli fammi sapere.