Quanto dovrebbero essere modulari le mie interfacce?

2

Mi sono imbattuto in un'istanza specifica in cui sembra che modularità e semplicità siano in conflitto l'una con l'altra. Di solito non è così, quindi non ero sicuro di come risolverlo.

Supponiamo che mi piacerebbe creare un'interfaccia queue :

template<typename T>
class queue {
 public:
  virtual ~queue() {}
  virtual void enqueue(const T& t) = 0;
  virtual void enqueue(T&& t) = 0;
  virtual T dequeue() = 0;
};

Mentre stavo realizzando un paio di implementazioni (alcune delle quali sono atomiche), ho notato che potevo davvero risparmiare tempo avendo una "classe astratta" che chiamava i metodi empty() o full() per aiutare a implementare le variabili di condizione. In questo modo qualsiasi implementazione di classe I sincronizzata potrebbe anche solo estendere quella "classe astratta". La classe astratta, a sua volta, ha implementato un'interfaccia estesa:

template<typename T>
class bounded_queue : public queue<T> {
public:
  virtual ~bounded_queue() {}
  virtual bool full() = 0;
  virtual bool empty() = 0;
};

Ma non sarebbe più semplice se avessi spinto quei metodi in queue , forse restituendo false di default? La risposta a questa domanda non è immediatamente ovvia per me. Se lo è, considera l'altra estremità dello spettro .

Non sono nemmeno sicuro che il disegno sopra (nel link) funzioni come previsto! Come posso decidere qualcosa di semplice, ma modulare?

    
posta VF1 02.08.2014 - 20:45
fonte

1 risposta

1

Dovrebbero essere nella stessa interfaccia. Limitato contro illimitato non cambia questo. La soluzione semplice consiste nel fornire implementazioni predefinite di isfull () e isempty () che una sottoclasse può sovrascrivere. [La mia risposta è molto simile ai commenti di @ tp1.]

Se non fornisci vuoto (), come può un chiamante determinare se richiedere o meno un dequio?

Dovresti anche considerare di includere un peek (). Una volta implementato isempty (), allora sia dequeue () che peek () possono bloccare o generare un'eccezione se chiamati su una coda vuota.

L'alternativa generale è fornire diversi tipi di coda. In questo caso una coda di blocco potrebbe essere una classe diversa, ma con la stessa interfaccia. Tuttavia lo stesso non si applica a una coda infinita, in cui isfull () non è mai vera.

    
risposta data 03.08.2014 - 09:09
fonte

Leggi altre domande sui tag