Quale è meglio: un gruppo di getter o 1 metodo con un parametro stringa di selezione?

15

Il nostro dominio della conoscenza coinvolge persone che camminano su una piastra di registrazione della pressione con i piedi nudi. Facciamo il riconoscimento dell'immagine che risulta in oggetti della classe 'Piede', se un piede umano è riconosciuto nei dati del sensore.

Ci sono diversi calcoli che devono essere eseguiti sui dati del piede.

Ora, quale API sarebbe meglio:

class Foot : public RecognizedObject  { 
  MaxPressureFrame getMaxPressureFrame();
  FootAxis getFootAxis();
  AnatomicalZones getAnatomicalZones();

  // + similar getters for other calculations

  // ...
}

o

class Foot : public RecognizedObject {
  virtual CalculationBase getCalculation(QString aName);

  // ...
}

Ora, ci sono molti pro e contro che posso inventare, ma non posso davvero decidere quali sono i più importanti. Nota, questa è un'applicazione per l'utente finale, non una libreria di software che vendiamo.

Qualche consiglio?

Alcuni professionisti del primo approccio potrebbero essere:

  • KISS - tutto è molto concreto. L'API, ma anche l'implementazione.
  • valori di ritorno strongmente digitati.
  • ereditare da questa classe è infallibile. Nulla può essere ignorato, aggiunto solo.
  • L'API è molto chiusa, niente entra, nulla può essere ignorato, quindi meno può andare male.

Alcuni contrari:

  • Il numero di getter crescerà, poiché ogni nuovo calcolo che inventiamo viene aggiunto all'elenco
  • È più probabile che l'API cambi, e se vengono introdotte modifiche di rottura, abbiamo bisogno di una nuova versione dell'API, una Foot2.
  • in caso di riutilizzo della classe in altri progetti, potremmo non aver bisogno di ogni calcolo

Alcuni professionisti per il secondo approccio:

  • più flessibile
  • è meno probabile che l'api cambi, (presumendo che l'astrazione sia corretta, in caso contrario, la modifica avrà un costo maggiore)

Alcuni contrari:

  • digitato in modo approssimativo. Ha bisogno di cast per ogni chiamata.
  • il parametro stringa - Ho delle sensazioni negative (ramificazione dei valori stringa ...)
  • Non esiste un caso / requisito di utilizzo corrente che richieda una flessibilità extra, ma potrebbe esserci in futuro.
  • l'API impone restrizioni: ogni calcolo deve derivare da una classe base. Ottenere un calcolo sarà forzato attraverso questo metodo 1, e passare parametri extra sarà impossibile, a meno che non escogitiamo un modo ancora più dinamico e super-flessibile di passare parametri che aumenti ancora di più la complessità.
posta Bgie 28.01.2014 - 15:23
fonte

2 risposte

6

Penso che nel primo approccio pagherà. Le stringhe magiche possono creare i seguenti problemi: Errori di battitura, uso improprio, sicurezza del tipo di ritorno non banale, mancanza di completamento del codice, codice non chiaro (questa versione ha questa caratteristica? Suppongo che lo scopriremo in fase di esecuzione). L'utilizzo delle enumerie risolverà alcuni di questi problemi, ma esaminiamo gli svantaggi sollevati:

  • Il numero di getter crescerà, poiché ogni nuovo calcolo che inventiamo viene aggiunto all'elenco

È vero, può essere fastidioso, tuttavia mantiene le cose belle e rigorose e ti dà il completamento del codice ovunque nel tuo progetto in qualsiasi IDE moderno, con buoni commenti di titolo che sono molto più utili delle enumerazioni.

  • È più probabile che l'API cambi, e se vengono introdotte modifiche di rottura, abbiamo bisogno di una nuova versione dell'API, una Foot2.

È vero, ma in realtà è un grande professionista;) è possibile definire interfacce per API parziali e quindi non è necessario ricompilare la classe dipendente che non sia influenzata dalle nuove API (quindi non è necessario per Foot2). Ciò consente un migliore disaccoppiamento, la dipendenza è ora dell'interfaccia e non dell'implementazione. Inoltre, se un'interfaccia esistente cambia, si avrà un errore di compilazione nelle classi dipendenti, che è ottimo per prevenire il codice non aggiornato.

  • in caso di riutilizzo della classe in altri progetti, potremmo non aver bisogno di ogni calcolo

Non vedo come usare le stringhe magiche o le enumerazioni ci aiuterà ... Se ho capito bene, o includi il codice nella classe Foot o lo suddivido in alcune classi più piccole, e questo vale per entrambe le opzioni

    
risposta data 28.01.2014 - 17:16
fonte
12

Vorrei raccomandare l'opzione 3: chiarire che i calcoli non sono una parte intrinseca dell'astrazione di un Foot , ma operare su di esso. Quindi puoi dividere Foot e i calcoli in classi separate, come questa:

class Foot : public RecognizedObject {
public:
    // Rather low-level API to access all characteristics that might be needed by a calculation
};

class MaxPressureFrame {
public:
    MaxPressureFrame(const Foot& aFoot); // Performs the calculation based on the information in aFoot
    //API for accessing the results of the calculation
};

// Similar classes for other calculations

In questo modo, hai ancora una strong digitazione del tuo calcolo e puoi aggiungerne di nuovi senza influire sul codice esistente (a meno che tu non abbia commesso un errore grave nella quantità di informazioni esposte da Foot ).

    
risposta data 28.01.2014 - 17:02
fonte