Domanda

In alcuni recenti progetti che ho preso parte in mi hanno quasi dipendente da seguente schema di codifica: (non sono sicuro se c'è un nome proprio per questo, ma comunque ...)

Diciamo che un oggetto si trova in uno stato determinato e abbiamo wa non per cambiare questo stato dall'esterno. Questi cambiamenti potrebbero significano qualsiasi comportamento, potrebbero invocare eventuali algoritmi, ma il fatto è che essi si concentrano su come cambiare lo stato (Stato membro, Stato dei dati, ecc ...) di qualche oggetto.

E chiamata in un modo discreto di let di cambiare quelle oggetto di un Mutator. Mutators sono applicati quando (generalmente) e hanno qualche metodo interno come apply(Target& target, ...), che immediatamente provoca modificare lo stato dell'oggetto (in effetti, sono una sorta di oggetti funzionali).

Inoltre potrebbe essere facilmente assimilata catene e applicato uno per uno (Mutator m1, m2, ...); si potrebbe anche derivare da alcune BasicMutator base con il metodo virtual void apply(...).

Ho introdotto classi denominate InnerMutator e ExplicitMutator che differiscono in termini di accesso - prima di loro anche in grado di cambiare il stato interno dell'oggetto e dovrebbe essere dichiarato come un amico (friend InnerMutator::access;)


In questi progetti la mia logica si rivolse a lavorare seguente modo:

  1. Preparare mutators disponibili, scegliere quale applicare
  2. Crea e impostare il object ad uno stato determinato
  3. foreach (mutator) mutator.apply(object);

Ora la domanda.

  

Questo schema Turnes di lavorare bene e    (a me) sembra come un campione di qualche disegno non-standard, ma utile   modello.

     

Quello che mi fa sentire a disagio è quella roba InnerMutator. I no   pensare dichiarando mutator un amico a   ogni oggetto che potrebbe essere stato   cambiato è una buona idea e mi wan't a   trovare l'alternativa appropriata.

     

Questo potrebbe essere risolto situazione in termini di Mutators o hai potuto   consigli certo modello alternativo con   lo stesso risultato?

Grazie.

È stato utile?

Soluzione

Spero che questo non è preso in attacco, ma non posso fare a meno di pensare questo disegno è una soluzione troppo di fantasia per una piuttosto semplice problema.

Perché è necessario mutators aggregati, per esempio? Si può semplicemente scrivere:

template <class T>
void mutate(T& t)
{
    t.mutate1(...);
    t.mutate2(...);
    t.mutate3(...);
}

Non è il tuo mutatore aggregato, solo che è una semplice funzione di modello basandosi su polimorfismo statico piuttosto che un elenco combinato di mutators facendo un super-mutatore.

Una volta ho fatto qualcosa che avrebbe potuto essere piuttosto simile. Feci oggetti funzione che potrebbero essere combinati dall'operatore && in oggetti funzionali eccellenti che applicati entrambi gli operandi (nell'ordine da sinistra a destra) in modo che si può scrivere codice come:

foreach(v.begin(), v.end(), attack && burn && drain);

E 'stato davvero bello e sembrava davvero intelligente per me al momento ed era abbastanza efficiente perché ha generato nuovi oggetti funzione al volo (nessun meccanismo di runtime coinvolti), ma quando i miei collaboratori lo vide, pensava che io fossi folle. Col senno di poi stavo cercando di stipare tutto in programmazione stile funzionale che ha la sua utilità, ma probabilmente non dovrebbe essere troppo invocati in C ++. Sarebbe stato abbastanza facile scrivere:

BOOST_FOR_EACH(Something& something, v)
{
    attack(something);
    burn(something);
    drain(something);
}

Certo è più righe di codice, ma ha il vantaggio di essere centralizzata e facile da eseguire il debug e non introdurre concetti alieni alle altre persone che lavorano con il mio codice. Ho trovato molto più vantaggioso, invece di concentrarsi sulla logica stretto piuttosto che cercare di ridurre la forza di righe di codice.

vi consiglio di pensare profondamente su questo e davvero considerare se vale la pena di continuare con questo disegno mutatore-based, non importa quanto intelligente e stretto è. Se altre persone non possono capire rapidamente, se non avete l'autorità di autori Boost, che sta per essere difficile convincere la gente a piacermi.

Per quanto riguarda InnerMutator, penso che si dovrebbe evitare come la peste. Avere classi mutatori esterne che possono modificare interni di una classe più direttamente possono qui sconfigge un sacco dello scopo di avere interni a tutti.

Altri suggerimenti

Non sarebbe meglio semplicemente fare quelle Mutators metodi delle classi che stanno cambiando? Se c'è funzionalità comuni si desidera diverse classi di avere allora perché non far loro ereditare dalla stessa classe di base? In questo modo si occuperà di tutto il disagio mutatore interno immagino.

Se si vuole fare la fila cambiamenti li potrebbe salvare come insiemi di chiamate di funzione ai metodi all'interno delle classi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top