Buon uso delle funzioni wrapper?

7

Che cosa consideri un buon uso delle funzioni del wrapper? Quando sono utili astrazioni e in quali casi una complessità dannosa e inutile?

    
posta paldepind 25.04.2011 - 20:37
fonte

3 risposte

16

Buoni usi per le funzioni wrapper:

  1. Nascondere la complessità di un'API a basso livello orribilmente complessa o non sicura, ad esempio l'API Win32. Tuttavia, il tuo wrapper deve effettivamente ridurre la complessità e / o aumentare la sicurezza per i casi più comuni.

  2. Creare qualcosa di multipiattaforma quando stai scrivendo una biblioteca generica o hai una buona ragione per credere che debba essere multipiattaforma.

Uso errato:

  1. Perché possiamo.

  2. Perché forse, a un certo punto, potremmo passare a un nuovo database nella nostra app rapida e sporca che stiamo scrivendo.

  3. Perché personalmente non mi piace l'API per qualche motivo di bikehed anche se il wrapper non nasconde effettivamente alcuna complessità.

risposta data 25.04.2011 - 20:45
fonte
3

Espandere la risposta @dsimcha (dando solo degli esempi) Solitamente avvolgo un certo numero di algoritmi C ++ STL, semplicemente perché sono tutti progettati in termini di iteratori, ma mi trovo a chiamarli su un'intera collezione per la maggior parte del tempo. / p>

Quindi:

template <typename RndIt>
void sort(RndIt begin, RndIt end);

diventa:

template <typename Container>
void sort(Container& c) { std::sort(c.begin(), c.end()); }

Piccolo guadagno, ma ancora:

  • Non riesco a rovinare e passare prima la fine e iniziare secondo
  • Rende il codice chiamante più leggibile

Può anche aiutare a introdurre i controlli di integrità, ad esempio l'algoritmo includes può essere chiamato solo se entrambe le raccolte sono ordinate ...

template <typename Big, typename Small>
bool includes(Big const& big, Small const& small) {
  assert(std::is_sorted(big.begin(), big.end()) && "big not sorted");
  assert(std::is_sorted(small.begin(), small.end()) && "small not sorted");
  return std::includes(big.begin(), big.end(), small.begin(), small.end());
}

Ovviamente l'utilizzo dell'STL in modalità di debug probabilmente eseguirà questo controllo, a seconda dell'implementazione ... o così posso sperare ... ma preferirei accertarmi:)

E c'è, infine, l'incarnazione di semplici idiomi. Ad esempio, è possibile cancellare elementi secondo un predicato in C ++ usando:

c.erase(std::remove_if(c.begin(), c.end(), pred), c.end());

Questo può essere racchiuso in:

template <typename Container, typename Pred>
void erase_if(Container& c, Pred pred);

semplicemente al codice del chiamante, e ancora una volta assicurati che non rovini gli argomenti / idioma.

    
risposta data 26.04.2011 - 20:53
fonte
1

Guarda qualsiasi modello dal framework Spring

Questo è un buon involucro in azione.

Hanno preso tutti i casi di uso comune per un'ampia varietà di tecnologie JEE standard (JPA, JMS, JAX-RS, JAXB ecc.) e hanno creato un insieme di modelli che fungono da semplici classi base da cui estendersi. Queste classi template semplificano notevolmente i casi di utilizzo semplici delle librerie e consentono agli sviluppatori di ottenere le basi in modo molto semplice. Una volta che hai trovato i tuoi piedi con la tecnologia richiesta, puoi esplorare le altre classi base fornite che avvolgono le classi più sofisticate.

Ciò che li rende così buoni è che tutti seguono un approccio molto simile, il che significa che una volta ottenuto il blocco di un modello, si avrà un buon vantaggio all'avvio successivo.

    
risposta data 25.04.2011 - 20:59
fonte

Leggi altre domande sui tag