Pesi Mosca e problema di fabbrica con IDisposable
-
22-09-2019 - |
Domanda
Mi sembra di essere mentalmente bloccato in un modello dilemma mosca.
Per prima cosa, diciamo che ho un tipo DisposableFiddle
usa e getta e un FiddleFactory
fabbrica:
public interface DisposableFiddle : IDisposable
{
// Implements IDisposable
}
public class FiddleFactory
{
public DisposableFiddle CreateFiddle(SomethingThatDifferentiatesFiddles s)
{
// returns a newly created fiddle.
}
}
Quindi, a mio parere, è abbastanza chiaro per il cliente di FiddleFactory
che la fabbrica non rivendica la proprietà del violino creato e che è responsabilità del cliente di disporre il violino quando fatto con esso.
Tuttavia, facciamo invece dire che voglio condividere violini tra i client utilizzando il modello mosca:
public class FiddleFactory
{
private Dictionary<SomethingThatDifferentiatesFiddles, DisposableFiddle> fiddles = new ...;
public DisposableFiddle CreateFiddle(SomethingThatDifferentiatesFiddles s)
{
// returns an existing fiddle if a corresponding s is found,
// or a newly created fiddle, after adding it to the dictionary,
// if no corresponding s is found.
}
}
Poi mi sento moralmente obbligato a fare la fabbrica stessa usa e getta, in quanto crea i violini e mantiene i riferimenti a loro durante tutto il loro ciclo di vita. Ma che potrebbe causare problemi ai clienti che assumevano che possedevano i violini e dovrebbe quindi disporli.
Il problema è in realtà che io chiamo la FiddleFactory
fabbrica invece di, diciamo, FiddlePool
, e la "creazione" metodo CreateFiddle
invece di GetFiddle
? In questo modo:
public class FiddlePool : IDisposable
{
private Dictionary<SomethingThatDifferentiatesFiddles, DisposableFiddle> fiddles = new ...;
public DisposableFiddle GetFiddle(SomethingThatDifferentiatesFiddles s)
{
// returns an existing fiddle if a corresponding s is found,
// or a newly created fiddle, after adding it to the dictionary,
// if no corresponding s is found.
}
// Implements IDisposable
}
Poi è chiaro al cliente che non sarà proprio il violino tornato ed è responsabilità del pool per smaltire i violini.
O può questo solo essere facilmente risolto documentazione-saggio?
C'è una via d'uscita dal dilemma? C'è anche un dilemma? : -)
Soluzione
Posso vedere due modi uscire da questo problema:
-
ThreadPool stile : ridisegnare le classi in modo che il
FiddlePool
fornisce un'interfaccia per fare le cose poco pratici. La piscina non distribuire le istanzeFiddle
perché ha un metodo diFiddlePool.PlayFiddle
invece. Dal momento che i tempi di vita controlli piscina violino, è responsabile del loro smaltimento. -
SqlConnection in stile : modificare metodo dispose pubblica di
Fiddle
in modo che in realtà solo torna violini al pool violino (quale la classe di violino incapsula). Internamente, la piscina violino si prende cura di davvero liberando risorse disponibili.
Altri suggerimenti
Sono d'accordo con il vostro secondo parere. La terminologia 'Pool' e 'Get' non rendere le cose più chiare per il consumatore. Tuttavia, ancora non rendere le cose abbastanza chiaro, e la documentazione deve sempre essere aggiunto al fine di garantire una piena comprensione valido.
Si dovrebbe fare qualcosa di più di una semplice documentazione e la denominazione di metodi per dire ai clienti di non chiamare smaltire. Davvero sarebbe meglio avere i clienti chiamano smaltire in modo da fare che il modello di utilizzo. Prendete un po 'direzione da nostre piscine di connessione al database sono costruiti.
Le piscine del database di un mazzo di collegamenti che si stanno piscina-aware. Chiamare codice crea una connessione, lo apre, e chiama vicino (dispose) su di esso. Il codice chiamante non ha nemmeno davvero sapere se è in pool o no, è tutto gestito internamente dalla classe di connessione. Con una connessione in pool, chiamando Open () viene ignorato se la connessione è già aperto. Close () / Dispose () viene chiamato e, nel caso di una connessione in pool questo in realtà restituisce la connessione al pool anziché chiuderla.
Si può fare la stessa cosa con la creazione di una classe PooledFiddle che prevale Dispose e restituisce l'oggetto alla piscina. Idealmente il cliente non avrebbe nemmeno bisogno di sapere che è un violino in pool.