来自于《Linux多线程服务端编程:使用 muduo C++网络库》/陈硕。
该工厂模式与对象池弱引用管理机制结合,使用弱引用表间接管理已创建对象,避免重复创建相同 key 的实例。同时,利用析构回调函数维护对象生命周期,保证了线程安全的对象回调与析构。
封装Product对象创建逻辑:
Factory的get()方法根据传入的key创建或返回Product对象,封装对象的创建过程。使用时仅仅需指定key,无需关心Product的具体实例化细节。
延迟实例化与解耦:
通过weak_ptr管理Product对象,仅在首次请求时创建实例(通过new Product(key)),后续请求复用现有对象,同时避免了shared_ptr循环引用导致的内存泄漏。在对象析构时通过weakDeleteCallback自动清理products_中的记录,来维护对象缓存。
本工厂模式与对象池区别在于:对象池主动管理可复用对象的存活,而该工厂模式仅被动跟踪对象生命周期。
class Factory : public boost::enable_shared_from_this<Factory>,
boost::noncopyable
{
public:
boost::shared_ptr<Product> get(const string& key)
{
boost::shared_ptr<Product> spProduct;
muduo::MutexLockGuard lock(mutex_);
boost::weak_ptr<Product>& wpProduct = Products_[key];
spProduct = wpProduct.lock(); // try to control spProduct
if (!spProduct)
{
// if failed, means spProduct doesn't exist
// new one and bind delete callback
spProduct.reset(new Product(key),
boost::bind(&Factory::weakDeleteCallback,
boost::weak_ptr<Factory>(shared_from_this()),
_1));
wpProduct = spProduct;
}
return spProduct;
}
private:
static void weakDeleteCallback(const boost::weak_ptr<Factory>& wpFactory,
Product* Product)
{
printf("weakDeleteProduct[%p]\n", Product);
boost::shared_ptr<Factory> factory(wpFactory.lock());
if (factory) {
factory->removeProduct(Product);
}else {
printf("factory died.\n");
}
delete Product; // sorry, I lied
}
void removeProduct(Product* Product)
{
if (Product)
{
muduo::MutexLockGuard lock(mutex_);
auto it = Products_.find(Product->key());
if (it != Products_.end() && it->second.expired())
{
Products_.erase(Product->key());
}
}
}
private:
mutable muduo::MutexLock mutex_;
std::map<string, boost::weak_ptr<Product> > Products_;
};