Ho uno sfondo C e sono un newb su C++. Ho una domanda di design di base. Ho una classe (lo chiamerò "chef" b/c il problema che ho sembra molto analogo a questo, sia in termini di complessità e problemi) che, in fondo funziona cosìAiuto C++ sul refactoring di una classe monster
class chef
{
public:
void prep();
void cook();
void plate();
private:
char name;
char dish_responsible_for;
int shift_working;
etc...
}
in pseudo-codice, questo viene implementato sulla falsariga di:
int main{
chef my_chef;
kitchen_class kitchen;
for (day=0; day < 365; day++)
{
kitchen.opens();
....
my_chef.prep();
my_chef.cook();
my_chef.plate();
....
kitchen.closes();
}
}
La classe di chef qui sembra essere una classe mostro, e ha il potenziale di diventare uno. cuoco sembra anche a violare il principio di un'unica responsabilità, così invece dovremmo avere qualcosa di simile:
class employee
{
protected:
char name;
int shift_working;
}
class kitchen_worker : employee
{
protected:
dish_responsible_for;
}
class cook_food : kitchen_worker
{
public:
void cook();
etc...
}
class prep_food : kitchen_worker
{
public:
void prep();
etc...
}
e
class plater : kitchen_worker
{
public:
void plate();
}
ecc ...
che sto certamente ancora lottando con il modo di implementarlo in fase di esecuzione in modo tale che, se per esempio il plater (o "chef nella sua veste di plater") decide di andare a casa a metà del servizio di cena, lo chef deve lavorare un nuovo turno.
Questo sembra essere correlato a una domanda più ampia che ho che se la stessa persona invariabilmente fa la preparazione, la cottura e la placcatura in questo esempio, qual è il reale vantaggio pratico di avere questa gerarchia di classi per modellare ciò che un singolo chef lo fa? Immagino che si imbatta nella "paura di aggiungere classi", ma allo stesso tempo, in questo momento o nel prossimo futuro, non penso che mantenere la classe dello chef nella sua interezza sia terribilmente ingombrante. Penso anche che sia in un senso molto reale più facile per un ingenuo lettore del codice vedere i tre diversi metodi nell'oggetto chef e andare avanti.
Capisco che potrebbe minacciare di diventare poco maneggevole quando/se aggiungiamo metodi come "cut_onions()", "cut_carrots()", ecc ..., ognuno con i propri dati, ma sembra che possano essere trattati con avendo facendo la funzione prep(), per esempio, più modulare. Inoltre, sembra che l'SRP portato alla sua logica conclusione creerebbe una classe "onion_cutters" "carrot_cutters" ecc ... e ho ancora difficoltà a vederne il valore, dato che in qualche modo il programma deve assicurarsi che il lo stesso dipendente taglia le cipolle e le carote che aiuta a mantenere la stessa variabile di stato attraverso i metodi (ad esempio, se il dipendente taglia le cipolle tagliate con le dita non è più idoneo a tagliare le carote), mentre nella classe mostro oggetto chef sembra che tutto ciò che si prende cura di
Naturalmente, capisco che questo diventa meno importante per avere un "design orientato agli oggetti" significativo, ma mi sembra che se dobbiamo avere oggetti separati per ciascuno dei compiti dello chef (che sembra innaturale, dato che la stessa persona sta facendo tutte e tre le funzioni), quindi sembra dare priorità alla progettazione del software rispetto al modello concettuale. Sento che un design orientato agli oggetti è utile qui se vogliamo avere, ad esempio, "meat_chef" "sous_chef" "three_star_chef" che sono probabilmente persone diverse. Inoltre, in relazione al problema del runtime è che c'è un sovraccarico di complessità che sembra, sotto la stretta applicazione del principio di responsabilità singola, che deve assicurarsi che i dati sottostanti che costituiscono il dipendente della classe base vengano modificati e che questo cambiamento sia riflessa in fasi temporali successive.
Sono quindi piuttosto tentato di lasciarlo più o meno così com'è. Se qualcuno potesse chiarire perché questa sarebbe una cattiva idea (e se hai suggerimenti su come meglio procedere) sarei molto grato.
A volte la mappatura veri ruoli mondo/responsabilità/attività agli oggetti nel codice semplicemente non funziona. Forse hai bisogno di qualche funzione generica che richiede una persona e un'azione. Quella funzione fa sì che la persona applichi l'azione. Il modulo –
su ogni interfaccia di classe potrebbe darti più indizi? come può fare un placcatore? cosa può fare cook_food? hanno bisogno di ereditare o è solo un'abilità (chiamata di funzione)? – billz
Guarda il metodo di composizione. O forse hai bisogno di uno schema di stato qui? –