Creare un'API dall'università per creare una classe

2

Diciamo che sto creando un'API per la classe University per creare un Class .  (Questo Class ha nome Class , Teacher e students ).

es .:

class Class{
       .. 

       private:
         std::string class_name_;
         Teacher teacher_;
         std::vector<Student> students_;
     };

    class University{
     public:   
       //API 1      
       void CreateClass(const std::string&, Teacher, std::vector<Student>);

       //API 2      
       void CreateClass(const std::string&, Teacher);

       //API 3      
       void CreateClass(const std::string&);      

         private:
        std::vector<Class> classes_;
        ..
    };

Pensa alla classe esattamente come Class che si trova nella tipica università.

Pensi che sia razionale avere API2 e API3? Ho fatto questa domanda perché quando ho iniziato a creare l'università di classe, ho iniziato con API1. Poi durante la metà del mio progetto ho capito che ho bisogno di API2 e API3 perché, io stava analizzando le informazioni di classe dal file (questo file contiene informazioni sulla classe) e non ho potuto avere tutte le informazioni in una volta durante l'analisi del file. Quindi, ho pensato di creare una classe vuota con solo un nome di classe prima quindi aggiungere studenti e insegnanti a quella specifica classe mentre analizzo ulteriormente il file.

Un'altra domanda: è contro il principio di progettazione orientata agli oggetti avere Classe con giusto nome? Lo chiedo perché normalmente Class ha insegnanti e studenti, quindi solo il suo chiamato Class .

Inoltre, in futuro, qualcuno potrebbe abusare dell'API3 per creare una classe vuota e non preoccuparsi di popolare l'insegnante e gli studenti, lasciando il Class vuoto.

    
posta vanta mula 17.10.2017 - 21:45
fonte

2 risposte

2

Questo dipende veramente dai requisiti che hai per la "Classe" che stai modellando.

Se ti aspetti che una classe esista senza averne assegnato uno studente, allora avrebbe senso che quel parametro fosse facoltativo nel costruttore (API 2). Gli utenti di "Classe" dovrebbero essere consapevoli che la variabile membro "studenti" può essere vuota;

Se ti aspetti che esista una classe che potrebbe non avere un insegnante assegnato per un periodo di tempo, allora avrebbe senso che anche quel parametro fosse opzionale (API 3). Gli utenti di "Classe" devono essere consapevoli che "insegnante_" può essere nullo (o avere un valore che rappresenta null);

D'altro canto, se ci si aspetta che ogni variabile membro in "Classe" abbia sempre un valore significativo, allora si dovrebbe implementare solo un costruttore che richiede che tutte le variabili siano impostate (API 1 in questo caso) .

Poiché nella tua domanda dici "Anche in futuro, qualcuno potrebbe abusare dell'API3 per creare una classe vuota e non preoccuparsi di popolare l'insegnante e gli studenti, questo lascia la Classe vuota." Questo per me significa che tu vuoi che "Class" contenga SEMPRE dati significativi. In realtà consideri l'API3 come un abuso della classe.

Per questo motivo dovresti avere solo API1. Se vuoi, puoi aggiungere argomenti di default a "Class" in modo che, mentre puoi istanziare una nuova "classe" con un solo parametro, il resto avrà per lo meno un valore reale in ogni momento.

Per quanto riguarda l'analisi dei file, tieni semplicemente i valori desiderati in una variabile separata finché non sei COMPLETAMENTE pronto per creare un'istanza della classe

ad esempio:

 std::string className = file.GetName();
 ...
 Teacher teacher = file2.GetTeacher();
 ...
 std::vector<Student> students = file3.GetStudents();
 //Now that we have all the data, we can properly instantiate the class
 Class newClass = Class(className, teacher, students);
    
risposta data 17.10.2017 - 22:11
fonte
2

Dipende da come vuoi che funzioni il tuo sistema.

Se puoi avere Class con solo un nome e nessun insegnante o studente, il metodo CreateClass(string) è appropriato. Ciò lascia la possibilità, come dici tu, che Class non ottenga mai un Teacher o Students . Se hai bisogno di avere un Teacher per la classe, allora CreateClass(string, Teacher) è appropriato, ma CreateClass(string) no. Se hai bisogno di un nome, insegnante e almeno uno studente, solo il primo è appropriato.

Il tuo University qui è, in funzione, un ClassFactory (almeno come scritto). Lo scopo di una classe factory è di prendere input validi (s) e creare un nuovo oggetto (nel tuo caso, un oggetto Class ). Solo tu sai quali sono questi input validi, però. Potresti voler leggere di più sul modello di fabbrica.

Come scritto, non hai fornito alcun modo per impostare le proprietà della classe Class , quindi è difficile dire quali sono le tue intenzioni. Sarà assegnato un Teacher in un secondo momento? Oppure è possibile modificare Teacher da quello iniziale? Può Students iscriversi a Class più tardi o devi sapere chi si iscriverà a Class prima di crearlo (sembra improbabile)? In che modo un utente o uno sviluppatore creerà questi Classes e quali informazioni avrà da loro? Una volta che rispondi a quelle domande e ad altri, i metodi necessari dovrebbero diventare molto più chiari.

Non c'è nulla di intrinsecamente sbagliato (OOP-saggio) dall'avere un Class con solo un nome, ma non Teacher o Students . Quelli sono vincoli derivati dalle tue esigenze. Molti oggetti hanno proprietà vuote o nulle, oppure liste / insiemi senza elementi. Al diavolo, alcuni oggetti potrebbero avere anche proprietà di stringa vuote, e nulla è sbagliato OOP-saggio.

La chiave è sapere quale sia uno stato valido per l'oggetto Class e verificare che tale oggetto sia in uno stato valido prima di usarlo (ad esempio, assicurandosi che abbia un Teacher e almeno 5 Students , così come un nome non vuoto e univoco).

    
risposta data 17.10.2017 - 22:09
fonte

Leggi altre domande sui tag