Che cosa consideri un buon uso delle funzioni del wrapper? Quando sono utili astrazioni e in quali casi una complessità dannosa e inutile?
Buoni usi per le funzioni wrapper:
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.
Creare qualcosa di multipiattaforma quando stai scrivendo una biblioteca generica o hai una buona ragione per credere che debba essere multipiattaforma.
Uso errato:
Perché possiamo.
Perché forse, a un certo punto, potremmo passare a un nuovo database nella nostra app rapida e sporca che stiamo scrivendo.
Perché personalmente non mi piace l'API per qualche motivo di bikehed anche se il wrapper non nasconde effettivamente alcuna complessità.
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:
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.
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.
Leggi altre domande sui tag functions abstraction