Come evitare di scrivere molte funzioni pass-through in un wrapper?

13

Ho una classe, che avvolge un'altra classe di un tipo di base comune. Poiché l'interfaccia del tipo di base è piuttosto ampia, ciò comporta la scrittura di molte funzioni pass-through. Sto cercando un modo per evitarlo.

Facciamo un esempio:

      Car
     /   \
Volvo     VolvoWithTrailer

Ora devo implementare ogni funzione nell'interfaccia dell'auto per VolvoWithTrailer e chiamare la funzione appropriata sull'oggetto avvolto Volvo, tranne forse GetMaxSpeed () che restituirà qualcosa di più basso. Fondamentalmente avrò molte funzioni come

int VolvoWithTrailer::GetNumSeats() {
  return mVolvo.GetNumSeats()
}

Un modo ovvio per risolvere questo problema è rendere VolvoWithTrailer una sottoclasse di Volvo

    Car
     |
   Volvo
     |
VolvoWithTrailer

ma ciò sembra violare il principio di favorire la composizione sull'ereditarietà.

In quale altro modo potrei evitare di scrivere tutti quei wrapper (il linguaggio è C ++)? Oppure - se questa è la tua posizione - perché dovrei semplicemente scriverli / usare solo l'ereditarietà? C'è qualche modello magico che potrebbe aiutarti?

    
posta Sarien 22.04.2013 - 23:30
fonte

2 risposte

5

La mia opinione è che dovresti scrivere qualunque cosa tu abbia bisogno di scrivere per migliorare la stabilità e la manutenibilità del programma a lungo termine . Qual è il punto in cui eviti di scrivere 20 righe di codice oggi, se ogni volta che tocchi qualcosa che utilizza questo codice o torni a mantenere questa classe, ti costa altri 5 minuti o più perché non hai messo il tempo oggi?

Quindi la domanda diventa "cosa devi scrivere?" Non penso che tu fornisca informazioni sufficienti per essere in grado di dare una risposta definitiva, quindi ti indicherò solo alcune cose a cui I penserebbe nel prendere una decisione:

1. Hai bisogno di avere l'oggetto Trailer da solo, ora o nel prossimo futuro? Se è così, hai una buona argomentazione per rendere il wrapper attorno ad entrambi gli oggetti compositi, dal momento che dovrai già completare l'uno o l'altro. Potrebbe anche essere coerente.

2. Qualcuno dei tre tipi (Car, Trailer, CarWithTrailer) si trova in un'area del codice in cui gli sviluppatori si inseriscono frequentemente o sembrano altrettanto desiderosi di farlo?
Se è così, sii molto attento, perché le conseguenze della scelta della cosa sbagliata possono essere molto costose ammortizzate ogni volta che il codice viene toccato. In caso contrario, potrebbe non fare alcuna differenza cosa tu decidi. Basta scegliere una direzione e andare con esso.

3. Cosa è più facile da capire?
Ci si avvicina saltando su di te che qualcuno che viene dietro di te immediatamente "ottiene" quello che stai cercando di fare? I tuoi compagni di squadra hanno pregiudizi particolari che potrebbero rendere un approccio più difficile da mantenere? Se tutte le cose sono uguali, scegli la soluzione che impone il carico cognitivo più basso.

4. Ci sono ulteriori vantaggi nell'usare un approccio rispetto ad un altro? Una cosa che mi viene in mente è che l'idea del wrapper ha un netto vantaggio se si scrive che CarWithTrailerWrapper può racchiudere qualsiasi auto e qualsiasi trailer in un CarWithTrailer. Quindi, finisci per scrivere tutti i tuoi metodi pass-through, ma li scrivi solo una volta , piuttosto che una volta per ogni classe di auto.

Questo rende il tuo investimento iniziale nella scrittura dei metodi di passaggio molto più economico quando aggiungi più automobili e trailer. Inoltre, aiuta a ridurre la tentazione di accoppiare le cose direttamente a Volvo o VolvoWithTrailer, riducendo al contempo le conseguenze dell'accoppiamento a CarWithTrailerWrapper, poiché si può fare molto di più con una sola implementazione.

Forse ci sono diversi vantaggi che potresti ottenere gratuitamente utilizzando il metodo di estensione, ma non li vedo.

OK, sembra che mi sia parlato per andare avanti e compilare i metodi pass-through, per applicazioni non banali.

Non sono un programmatore C ++, quindi non ho idea di quali strumenti di generazione del codice sono disponibili per te. L'IDE che uso può generare metodi da un'interfaccia e posso aggiungere codice modelli che renderebbero abbastanza indolore la scrittura di pass-through. Se non hai accesso a un IDE che esegue questa operazione, puoi effettivamente ottenere molto lontano lasciando Excel scrivi il codice per te .

    
risposta data 23.04.2013 - 03:53
fonte
3

Because the base type interface is quite large this involves writing a lot of pass-through functions.

E c'è il tuo problema.

Le interfacce dovrebbero gestire una sola responsabilità. Mantenerli snelli e concentrati limita la quantità di lavoro passthrough che potrebbe essere necessario fare in caso di decoratore, proxy o altro wrapper (oltre a rendere il simulatore di classe da usare, testare, mantenere ed estendere).

    
risposta data 22.04.2013 - 23:36
fonte

Leggi altre domande sui tag