Při vytváření aplikací často narazíte na objekty, jejichž vytvoření je poměrně nákladné. V některých scénářích jsou náklady na vytváření nových objektů dostatečně vysoké, aby ovlivnily výkon aplikace. Tady přichází na pomoc návrhový vzor fondu objektů.
Návrhový vzor fondu objektů je kreační návrhový vzor, který se používá k recyklaci objektů, nikoli k jejich opětovnému vytvoření pokaždé, když je aplikace potřebuje. Udržováním opakovaně použitelných instancí objektů ve fondu prostředků a jejich dolingem podle potřeby pomáhá tento vzor minimalizovat režii inicializace, vytváření instancí a likvidace objektů a zvýšit výkon vaší aplikace.
Když aplikace požaduje objekt a objekt je dostupný z fondu, je vrácen z fondu. Pokud objekt požadovaného typu není k dispozici z fondu, je vytvořena a vrácena nová instance objektu. Když aplikace již objekt nepotřebuje, objekt se odešle zpět do fondu.
Je možné konfigurovat minimální a maximální počet objektů, které může obsahovat fond objektů. Pokud aplikace potřebuje objekt z fondu, ale byl přidělen maximální počet objektů, může typická implementace vlastního fondu objektů přijmout jednu nebo více z následujících strategií:
- Vrátit null nebo vyvolat výjimku
- Blokujte hovor, dokud nebude k dispozici objekt
- Zvětšete velikost bazénu, aby se do něj vešlo více objektů
Fond objektů je podobný fondu připojení k databázi. Stejně jako fond připojení řídí maximální počet připojení k databázi, fond objektů řídí počet instancí třídy, které aplikace použije.
Vytvoření fondu obecných objektů v C #
Nyní, když víme základní, pojďme se podívat na implementaci. Při implementaci návrhového vzoru fondu objektů musíme vzít v úvahu opětovnou použitelnost, jednoduchost, konfigurovatelnost a dokonce i faktory, jako je bezpečnost podprocesů.
V tomto příkladu využijeme a ConcurrentBag
třída pro ukládání objektů. Všimněte si, že ConcurrentBag
třída v System.Collections.Concurrent
namespace provides a lock-free, thread-safe, unordered collection of elements. Pamatujte také, že vkládání a vyjímání objektů do a z ConcurrentBag
je velmi rychlý - zvláště pokud se stejné vlákno pokouší současně vkládat a odebírat položky ze sbírky.
Zde je struktura našeho zvyku ObjectPool
třída. Všimněte si použití ConcurrentBag
instance pro ukládání objektů.
veřejná třída ObjectPool, kde T: new (){
private readonly ConcurrentBag items = new ConcurrentBag ();
private int counter = 0;
soukromý int MAX = 10;
public void Release (položka T)
{
//DĚLAT
}
public T Get ()
{
//DĚLAT
}
}
Následující fragment kódu ilustruje implementaci Dostat
metoda. The Dostat
metoda vrátí instanci z fondu objektů, pokud je k dispozici. Pokud žádný není k dispozici, vytvoří se a vrátí se nový objekt. V obou těchto scénářích čelit
proměnná se podle potřeby zvyšuje nebo snižuje. Všimněte si, že protože používáme souběžnou sbírku, tj. ConcurrentBag
v tomto příkladu je postaráno o souběžnost.
public T Get (){
Položka T;
if (items.TryTake (out item))
{
čelit-;
vrátit položku;
}
jiný
{
T obj = new T ();
items.Add (obj);
counter ++;
návrat obj;
}
}
The MAX
celočíselná proměnná je zde pevně zakódována, ale můžete ji konfigurovat. Tato třída není uzavřená ani statická, takže ji můžete libovolně rozšířit.
The Uvolnění
metoda se používá k uvolnění objektů, které již nejsou potřeba, zpět do fondu objektů. Zkontroluje, zda je hodnota čelit
proměnná je menší než hodnota MAX
proměnná, a pokud ano, přidá objekt předaný jako parametr do kolekce.
public void Release (položka T){
if (počitadlo <MAX)
{
items.Add (item);
counter ++;
}
}
Za předpokladu, že jste vytvořili třídu s názvem Moje třída
, takto jej můžete přidat do fondu objektů pomocí ObjectPool
třída.
static void Main (řetězec [] args){
ObjectPool objPool = nový ObjectPool ();
MyClass obj = objPool.Get ();
objPool.Release (obj);
Console.Read ();
}
Tuto implementaci vlastního fondu objektů můžete upravit tak, aby umožňovala čtení minimální a maximální velikosti fondu z konfiguračního souboru. V rámci inicializace fondu objektů můžete také zajistit, aby fond obsahoval v něm minimální počet objektů.
Fondy objektů pomáhají snižovat režii prostředků, když potřebujete více instancí třídy, jejichž vytváření nebo správa je nákladná. Pokud vaše aplikace zahrnuje vytváření instancí stejných tříd znovu a znovu, použijte tento návrhový vzor k zajištění optimálního výkonu.