Let us discuss how object pool design pattern in this article:
The object pool pattern is a creational design pattern. In this pattern, first you create a set of objects (a pool), then you acquire & release objects from the pool, instead of constantly creating and releasing them.
Properly used pool can improve the app performance. In iOS it’s being used by table view, collection view and DispatchQueue.
The object pool pattern manages a collection of reusable objects that are provided to consumer. A consumer requests an object from the pool if exists, uses it to perform work, and returns it to the pool so that it can be reuse for future requests. If object doesn’t exist in pool then it is created and store in object pool against an identifier.
The object pool pattern hides the construction of objects from the consumer.
Use this pattern when you have a number of identical objects whose creation you need to manage, either because the objects represent real-world resources or because creating new instances is expensive.
When there can be only one object in existence at any moment or no limits on the number of objects that can exist
When objects are getting reuse correctly plus ensure thread safety
Singleton pattern but manages a single object.
Perfect example of object pool is thread pool. A thread pool is a pattern for achieving concurrency of execution in a computer program. A thread pool maintains multiple threads waiting for tasks to be allocated for concurrent execution by the supervising program. By maintaining a pool of threads, the model increases performance and avoids latency in execution due to frequent creation and destruction of threads for short-lived tasks.
Let’s say you have to create a payment widget that supports multiple payment methods. Now each payment method has different behavior so you could have a separate presenter to handle each method functionality. There are chances that the payment method may vary per user so it doesn’t make sense to create a presenter object for free for unwanted payment methods, also it doesn’t make sense to create presenter object each time when required. Here object pool pattern comes in handy.
enum PaymentMethod {
case creditCard
case debitCard
case wallet
case cash
}
protocol PaymentPresenterStrategy {}
protocol MethodsPresenterResolvable {
func register(methods: [PaymentMethod])
func resolvePresenter(for method: PaymentMethod) -> PaymentPresenterStrategy?
}
final class MethodsPresenterResolver: MethodsPresenterResolvable {
private var presenterCache: [PaymentMethod: PaymentPresenterStrategy]?
func register(methods: [PaymentMethod]) {
var cache = [PaymentMethod: PaymentPresenterStrategy]()
for method in methods {
guard let paymentPresenter = presenter(for: method) else {
continue
}
cache[method] = paymentPresenter
}
presenterCache = cache
}
func resolvePresenter(for method: PaymentMethod) -> PaymentPresenterStrategy? {
return presenterCache?[method]
}
private func presenter(for method: PaymentMethod) -> PaymentPresenterStrategy? {
switch method {
case .creditCard:
return CreditCardPresenter()
case .debitCard:
return DebitCardPresenter()
case .wallet:
return WalletPresenter()
case .cash:
return CashPresenter()
}
}
}
final class CreditCardPresenter: PaymentPresenterStrategy {}
final class DebitCardPresenter: PaymentPresenterStrategy {}
final class WalletPresenter: PaymentPresenterStrategy {}
final class CashPresenter: PaymentPresenterStrategy {}
This example first registers required presenter against available payment methods for user and then consumer on demand requests presenter from the pool.
This is a free third party commenting service we are using for you, which needs you to sign in to post a comment, but the good bit is you can stay anonymous while commenting.