Quali sono i Mixins (come concetto)
Sto cercando di ottenere la mia testa intorno al Mixin concetto, ma non riesco a capire di cosa si tratta.
A mio modo di vedere è che è un modo per espandere le funzionalità di una classe utilizzando l’ereditarietà.
Ho letto che le persone si riferiscono a loro come “astratto sottoclassi”. Qualcuno può spiegare perché?
Ti sarei grato se devi spiegare la tua risposta in base al seguente esempio (Da uno dei miei conferenza presentazioni):
- Un quadro che fa un uso pesante di mixins è Apache Arazzo per le applicazioni web Java. Leggere la documentazione e guardare alcuni esempi di Arazzi e forse si sarà in grado di vedere i paralleli/modelli di ciò che si sta vedendo in C++ esempio. Ecco un link: tapestry.apache.org/component-mixins.html
- Avevo completamente pensato che si stava parlando di Ruby basta uno sguardo del titolo…
Prima di andare in quello che un mix-in, è utile descrivere i problemi che cerca di risolvere. Diciamo che avete un sacco di idee o concetti che si sta tentando di modello. Essi possono essere in qualche modo correlati, ma sono ortogonali per la maggior parte-il che significa che si può stare da soli in modo indipendente. Ora si potrebbe modello di questo attraverso l’ereditarietà e ognuno di quei concetti che derivano da alcuni comuni classe di interfaccia. Quindi è fornire strumenti concreti in derivati di classe che implementa l’interfaccia.
Il problema con questo approccio è che questa struttura non offre alcuna chiara e intuitiva per prendere ciascuna di tali classi concrete e combinarli insieme.
L’idea con mix-ins è quello di fornire un sacco di classi primitive, dove ognuno di essi i modelli di una base ortogonale concetto, e di essere in grado di attaccare insieme per comporre più complesse classi con solo le funzionalità che si desidera-un po ‘ come i lego. Le classi primitive stessi sono destinati ad essere utilizzati come blocchi di costruzione. Questo è estensibile, dal momento che in seguito si possono aggiungere altre classi primitive per la raccolta senza modificare quelli esistenti.
Tornando al C++, una tecnica per farlo è con l’utilizzo di modelli e di eredità. L’idea di base è che si collega questi blocchi di costruzione, offrendo loro tramite il parametro del modello. Quindi catena insieme, ad esempio. via
typedef
, per formare un nuovo tipo contenente le funzionalità che si desidera.Prendendo il tuo esempio, diciamo che si desidera aggiungere un ripristino funzionalità. Ecco come potrebbe sembrare:
Si noterà che ho fatto un paio di modifiche dall’originale:
value_type
per il secondo modello param per rendere il suo utilizzo meno ingombrante. In questo modo non è necessario digitare<foobar, int>
ogni volta che ti infili un pezzo insieme.typedef
è utilizzato.Di notare che questo è destinato ad essere un semplice esempio per illustrare il mix-in idea. In modo da non prendere in considerazione casi particolari e divertenti usi. Per esempio, l’esecuzione di un
undo
senza mai segnare un numero probabilmente non si comportano come ci si potrebbe aspettare.Come una nota a margine, si potrebbe anche trovare in questo articolo utile.
void Number::set(int)
eint Number::get() const
dovrebbe esserevirtual
per ottenere il mixin comportamento quando si utilizza unNumber*
puntatore.set
eget
virtuale ha un senso, perché si può quindi definirevoid doubler(Number &n){ n.set(n.get()*2); }
e di essere in grado di utilizzare con annullabili e reundoable classiNumber::value_type
è già definito, potrebbe (e dovrebbe) essere utilizzato anche perNumber::n
,Number::get
eNumber::set
.int
,std::string
,char
, ecc in C++) sono essi stessi mixins, giusto?Mixin è una classe dessigned per fornire funzionalità di un’altra classe, di norma, attraverso una specifica classe che fornisce le funzionalità di base che le esigenze di funzionalità. Per esempio, si consideri il tuo esempio:
Il mixin in questo caso fornisce la funzionalità di annullamento dell’operazione di impostazione di un valore di classe. Questo maggior traspirabilità è basato sul
get/set
funzionalità fornite da una parametrizzazione di classe (IlNumber
classe, nel tuo esempio).Un altro esempio (Estratta da “Mixin a base di programmazione in C++“):
In questo esempio, il mixin fornisce le funzionalità di contare i vertici, dato un grafo classe che esegue operazioni trasversali.
Comunemente, in C++ mixins sono attuate attraverso la CRTP idioma. Questo thread potrebbe essere una buona lettura su un mixin implementazione in C++: Che cosa è il C++, Mescolandosi Stile?
Qui è un esempio di un mixin che sfrutta il CRTP idioma (Grazie a @Semplici):
Questo mixin fornisce le funzionalità di eterogenei copia per un set (gerarchia) di forma le classi.
base<derived>
, quindi non si può avere un contenitore dibase*
oggetti. Inoltre, una classe astratta utilizzavirtual
funzione che comportano sovraccarico di runtime; con CRTP si utilizzastatic_cast
chiamare le funzioni membro in classe derivata che vengono risolti in modo statico a tempo di compilazione.shape
classe, ma derivanti dacloneable_shape
implementa automaticamente ilclone
funzione membro per voi, in modo da non dovete scrivere voi stessi per ogni classe si deriva.Mi piace la risposta da greatwolf, ma di offrire un punto di attenzione.
greatwolf ha dichiarato, “Le funzioni virtuali, in verità, non necessaria, perché sappiamo esattamente che cosa il nostro composto per il tipo di classe è a tempo di compilazione.” Purtroppo, si può incorrere in qualche comportamento incoerente se si utilizza l’oggetto polymorphically.
Mi permetta di modificare la funzione principale dal suo esempio:
Facendo il “set” funzione virtuale, il corretto ignorare verrà chiamato e il comportamento incoerente di cui sopra non si verifica.
Mixins in C++ sono espresse utilizzando il Curiosamente Ricorrenti Modello Di Modello (CRTP). Questo post è un’eccellente ripartizione di ciò che essi forniscono più di altri riutilizzo tecniche di… a tempo di compilazione polimorfismo.
Questo funziona come un’interfaccia e forse di più, in modo astratto, ma le interfacce sono più facili da ottenere prima volta.
Risolve molti problemi, ma quello che ho trovare in via di sviluppo che viene su un lotto api esterne. immaginate questo.
Si dispone di un database di utenti, il database ha un certo modo di ottenere l’accesso ai suoi dati.
ora immaginate di avere facebook, che ha anche un certo modo di ottenere l’accesso ai dati (api).
in qualsiasi momento la tua applicazione potrebbe essere necessario eseguire utilizzando i dati di facebook o il tuo database. così che cosa dovete fare è creare un’interfaccia che dice “tutto ciò che implementa mi sta per sicuramente hanno i seguenti metodi” ora, è possibile implementare l’interfaccia nelle applicazioni…
perché l’interfaccia promesse che l’implementazione di archivi avrà i metodi dichiarati in loro, sai che ovunque o ogni volta che si utilizza l’interfaccia dell’applicazione, se si passa i dati, si sta andando sempre di avere i metodi per la definizione e quindi avere i dati per lavorare fuori di.
Ci sono molti più livelli di questo modello di lavoro, ma la sostanza è che è un bene perché, dati o altri tali persistenti elementi di diventare una grande parte della vostra applicazione, e se cambiano senza che tu lo sappia, l’applicazione può rompere 🙂
Ecco alcuni pseudo-codice.
Per capire il concetto dimenticare classi per un momento. Pensare (più popolare) di JavaScript. Dove gli oggetti sono matrici dinamiche di metodi e proprietà. Callable con il loro nome come simbolo o come una stringa letterale. Come implementare in C++ standard in un anno 2018? Non facilmente. Ma che è il nucleo del concetto. In JavaScript si possono aggiungere e rimuovere (aka mix-in) ogni volta che è e ciò che si desidera. Molto importante: Non ereditarietà di classe.
Ora su C++. In C++ Standard e dispone di tutto il necessario, non serve come una dichiarazione di qui. Ovviamente non voglio scrivere un linguaggio di scripting per attuare mix-in, utilizzando il C++.
Sì, questo è un buon articolo , ma per l’ispirazione. CRTP non è una panacea. E anche il cosiddetto approccio accademico è qui, anche (in sostanza) CRTP base.
Prima del down-voto questa risposta forse prendere in considerazione il mio p.o.c. codice bacchetta box 🙂