Пул об'єктів (англ. Object pool) — твірний шаблон проєктування, набір ініціалізованих і готових до використання об'єктів. Коли системі потрібно об'єкт, він не створюється, а береться з пулу. Коли об'єкт більше не потрібен, він не знищується, а повертається в пул.
Призначення
Пул об'єктів призначений для зберігання готових до використання об'єктів. Коли система потребує новий об'єкт, він запрошується з пула, нехтуючи процесом породження. А після використання повертається назад в пул замість знищення.
Умови використання
Шаблон використовується для підвищення продуктивності, якщо:
- об'єкти часто створюються і знищуються;
- система має обмежену кількість типів об'єктів, що зберігаються в Пулі.
- створення чи знищення об'єкта є дуже затратною операцією.
Пул об'єктів може працювати як з інтерфейсами, так і з конкретними реалізаціями. Все залежить від архітектури системи, що розробляється та розв'язуваних задач.
Пул та інші шаблони
Можна зустріти сумісне використання Пула об'єктів та інших шаблонів проєктування. Наприклад, для створення об'єктів в конкретному стані можна використати Прототип. А за допомогою Одинака — створити єдиний екземпляр Пула в системі.
Поганою практикою вважається приховування Пула за іншими шаблонами проєктування. Розробник, який використовує такий підхід, не очікує вимоги повернення об'єктів, наприклад, Фабричного методу. А без повернення об'єктів сам Пул стає непотрібним. В такому випадку, правильним рішенням буде відділити реалізацію класів, що створюють об'єкти.
Особливості використання
Пул нічого не знає про реалізацію об'єктів, які зберігаються. Тому вважається, що повернений об'єкт знаходиться в невизначеному стані. Для подальшого використання його необхідно перевести в початковий стан (скидання). Наявність об'єктів в невизначеному стані перетворює Пул в «об'єктну клоаку» (object cesspool). Повторне використання може стати причиною витоку конфіденційної інформації. Тому обов'язково необхідно зчищати поля з секретними даними при скиданні, а самі дані — знищувати. Можлива ситуація, коли в Пулі не залишиться вільних об'єктів. В такому випадку, реакція на запит може бути наступною:
- збільшення розміру пула;
- відмова у видачі об'єкта;
- становлення в чергу і очікування звільнення об'єкта.
Реалізація
Реалізація на C#
Роздивимось варіант роботи з Пулом без обмежень в його розмірі. В такому випадку в нього можна помістити стільки об'єктів, скільки підтримує використовуємий контейнер. Якщо ж при запиті не виявиться вільного об'єкта, то буде створений новий.
В загальному випадку Пул не повинен нічого знати про спосіб створення, реалізацію і функції об'єктів, що зберігаються. Для нього важливим є тільки мати можливість дати команду скидання стану.
Створимо два інтерфейси. Перший — для скидання стану, його повинні підтримувати самі об'кти:
/// <summary> The poolable object interface </summary> public interface IPoolable { /// <summary>Resets the object's state.</summary> void ResetState(); }
Другий — для створення об'єктів, тому що Пул не знає як саме це робити. Тут може бути як варіант з одним ключовим словом new, так і використання будь-якого шаблона проєктування.
/// <summary> The pool object creator interface. </summary> /// <typeparam name="T">Type of the objects to create.</typeparam> public interface IPoolObjectCreator<T> { /// <summary>Creates new object for a pool.</summary> /// <returns>The object.</returns> T Create(); }
Одразу реалізуємо даний інтерфейс у вигляді generic класу для створення екземплярів за допомогою конструктора без параметрів:
public class DefaultObjectCreator<T> : IPoolObjectCreator<T> where T : class, new() { T IPoolObjectCreator<T>.Create() { return new T(); } }
Перейдемо до створення Пула. Як контейнер об'єктів використовуємо клас ConcurrentBag, реалізований в .NET4. Оскільки розмір Пула не фіксований, то його метод GetObject() завжди повертає об'єкт. Метод ReturnObject() переміщує об'єкт назад у контейнер. При цьому відбувається скидання його стану. Крім того, змінній, що тримала посилання на нього, присвоюється значення null. Властивість Count показує скільки об'єктів в даний момент знаходиться в пулі.
Повний код класу, що реалізує шаблон Пул об'єктів:
public class ObjectPool<T> where T : class, IPoolable { /// <summary>Object container. ConcurrentBag is tread-safe class.</summary> private readonly ConcurrentBag<T> _container = new ConcurrentBag<T>(); /// <summary>Object creator interface.</summary> private readonly IPoolObjectCreator<T> _objectCreator; /// <summary>Total instances.</summary> public int Count { get { return this._container.Count; } } /// <summary> /// Initializes a new instance of the <see cref="T:ObjectPool"/> class. /// </summary> /// <param name="creator">Interface of the object creator. It can't be null.</param> public ObjectPool(IPoolObjectCreator<T> creator) { if (creator == null) { throw new ArgumentNullException("creator can't be null"); } this._objectCreator = creator; } /// <summary>Gets an object from the pool.</summary> /// <returns>An object.</returns> public T GetObject() { T obj; if (this._container.TryTake(out obj)) { return obj; } return this._objectCreator.Create(); } /// <summary>Returns the specified object to the pool.</summary> /// <param name="obj">The object to return.</param> public void ReturnObject (ref T obj) { obj.ResetState(); this._container.Add(obj); obj = null; } }
Джерела
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Pul ob yektiv angl Object pool tvirnij shablon proyektuvannya nabir inicializovanih i gotovih do vikoristannya ob yektiv Koli sistemi potribno ob yekt vin ne stvoryuyetsya a beretsya z pulu Koli ob yekt bilshe ne potriben vin ne znishuyetsya a povertayetsya v pul Zmist 1 Priznachennya 2 Umovi vikoristannya 3 Pul ta inshi shabloni 4 Osoblivosti vikoristannya 5 Realizaciya 5 1 Realizaciya na C 6 DzherelaPriznachennyared Pul ob yektiv priznachenij dlya zberigannya gotovih do vikoristannya ob yektiv Koli sistema potrebuye novij ob yekt vin zaproshuyetsya z pula nehtuyuchi procesom porodzhennya A pislya vikoristannya povertayetsya nazad v pul zamist znishennya Umovi vikoristannyared Shablon vikoristovuyetsya dlya pidvishennya produktivnosti yaksho ob yekti chasto stvoryuyutsya i znishuyutsya sistema maye obmezhenu kilkist tipiv ob yektiv sho zberigayutsya v Puli stvorennya chi znishennya ob yekta ye duzhe zatratnoyu operaciyeyu Pul ob yektiv mozhe pracyuvati yak z interfejsami tak i z konkretnimi realizaciyami Vse zalezhit vid arhitekturi sistemi sho rozroblyayetsya ta rozv yazuvanih zadach Pul ta inshi shablonired Mozhna zustriti sumisne vikoristannya Pula ob yektiv ta inshih shabloniv proyektuvannya Napriklad dlya stvorennya ob yektiv v konkretnomu stani mozhna vikoristati Prototip A za dopomogoyu Odinaka stvoriti yedinij ekzemplyar Pula v sistemi Poganoyu praktikoyu vvazhayetsya prihovuvannya Pula za inshimi shablonami proyektuvannya Rozrobnik yakij vikoristovuye takij pidhid ne ochikuye vimogi povernennya ob yektiv napriklad Fabrichnogo metodu A bez povernennya ob yektiv sam Pul staye nepotribnim V takomu vipadku pravilnim rishennyam bude viddiliti realizaciyu klasiv sho stvoryuyut ob yekti Osoblivosti vikoristannyared Pul nichogo ne znaye pro realizaciyu ob yektiv yaki zberigayutsya Tomu vvazhayetsya sho povernenij ob yekt znahoditsya v neviznachenomu stani Dlya podalshogo vikoristannya jogo neobhidno perevesti v pochatkovij stan skidannya Nayavnist ob yektiv v neviznachenomu stani peretvoryuye Pul v ob yektnu kloaku object cesspool Povtorne vikoristannya mozhe stati prichinoyu vitoku konfidencijnoyi informaciyi Tomu obov yazkovo neobhidno zchishati polya z sekretnimi danimi pri skidanni a sami dani znishuvati Mozhliva situaciya koli v Puli ne zalishitsya vilnih ob yektiv V takomu vipadku reakciya na zapit mozhe buti nastupnoyu zbilshennya rozmiru pula vidmova u vidachi ob yekta stanovlennya v chergu i ochikuvannya zvilnennya ob yekta Realizaciyared Realizaciya na C red Rozdivimos variant roboti z Pulom bez obmezhen v jogo rozmiri V takomu vipadku v nogo mozhna pomistiti stilki ob yektiv skilki pidtrimuye vikoristovuyemij kontejner Yaksho zh pri zapiti ne viyavitsya vilnogo ob yekta to bude stvorenij novij V zagalnomu vipadku Pul ne povinen nichogo znati pro sposib stvorennya realizaciyu i funkciyi ob yektiv sho zberigayutsya Dlya nogo vazhlivim ye tilki mati mozhlivist dati komandu skidannya stanu Stvorimo dva interfejsi Pershij dlya skidannya stanu jogo povinni pidtrimuvati sami ob kti lt summary gt The poolable object interface lt summary gt public interface IPoolable lt summary gt Resets the object s state lt summary gt void ResetState Drugij dlya stvorennya ob yektiv tomu sho Pul ne znaye yak same ce robiti Tut mozhe buti yak variant z odnim klyuchovim slovom new tak i vikoristannya bud yakogo shablona proyektuvannya lt summary gt The pool object creator interface lt summary gt lt typeparam name T gt Type of the objects to create lt typeparam gt public interface IPoolObjectCreator lt T gt lt summary gt Creates new object for a pool lt summary gt lt returns gt The object lt returns gt T Create Odrazu realizuyemo danij interfejs u viglyadi generic klasu dlya stvorennya ekzemplyariv za dopomogoyu konstruktora bez parametriv public class DefaultObjectCreator lt T gt IPoolObjectCreator lt T gt where T class new T IPoolObjectCreator lt T gt Create return new T Perejdemo do stvorennya Pula Yak kontejner ob yektiv vikoristovuyemo klas ConcurrentBag realizovanij v NET4 Oskilki rozmir Pula ne fiksovanij to jogo metod GetObject zavzhdi povertaye ob yekt Metod ReturnObject peremishuye ob yekt nazad u kontejner Pri comu vidbuvayetsya skidannya jogo stanu Krim togo zminnij sho trimala posilannya na nogo prisvoyuyetsya znachennya null Vlastivist Count pokazuye skilki ob yektiv v danij moment znahoditsya v puli Povnij kod klasu sho realizuye shablon Pul ob yektiv public class ObjectPool lt T gt where T class IPoolable lt summary gt Object container ConcurrentBag is tread safe class lt summary gt private readonly ConcurrentBag lt T gt container new ConcurrentBag lt T gt lt summary gt Object creator interface lt summary gt private readonly IPoolObjectCreator lt T gt objectCreator lt summary gt Total instances lt summary gt public int Count get return this container Count lt summary gt Initializes a new instance of the lt see cref T ObjectPool gt class lt summary gt lt param name creator gt Interface of the object creator It can t be null lt param gt public ObjectPool IPoolObjectCreator lt T gt creator if creator null throw new ArgumentNullException creator can t be null this objectCreator creator lt summary gt Gets an object from the pool lt summary gt lt returns gt An object lt returns gt public T GetObject T obj if this container TryTake out obj return obj return this objectCreator Create lt summary gt Returns the specified object to the pool lt summary gt lt param name obj gt The object to return lt param gt public void ReturnObject ref T obj obj ResetState this container Add obj obj null Dzherelared http andrey moveax ru patterns oop creational object pool http dofactory com Default aspx Otrimano z https uk wikipedia org w index php title Pul ob 27yektiv shablon proyektuvannya amp oldid 33329596