webrtc对criticalsection进行了包装,可以实现在windows和支持posix平台使用锁。
基本结构如下:
在工厂方法中去负责具体类的对象的创建,可以称之为简单工厂模式,一个工厂负责所有产品的创建,通过向工厂传入必要的参数来进行不同产品的创建,一般创建的产品是有关系的,它们共同继承自一个抽象类。
针对CriticalSectionWrapper,可以把它看做是一个工厂,它拥有一个工厂方法CreateCriticalSection。它负责创建具体的实例对象,它传入的参数很特别,是个宏,处于windows环境创建windows对象,处于posix环境,创建posix对象。
这个还有一点特别之处是工厂类同时还是产品类的抽象基类,即工厂负责生产产品,同时它由有抽象产品的接口。
如果换种方案来看,将Enter和Leave方法放到另一个抽象类中,作为具体产品的基类,其实也是可以的,工厂方法返回基类的指针。
具体代码如下,抽象类,有一个工厂方法
class CriticalSectionWrapper { public: // Factory method, constructor disabled static CriticalSectionWrapper* CreateCriticalSection(); virtual ~CriticalSectionWrapper() {} // Tries to grab lock, beginning of a critical section. Will wait for the // lock to become available if the grab failed. virtual void Enter() = 0; // Returns a grabbed lock, end of critical section. virtual void Leave() = 0; };
具体的工厂方法
CriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection() { #ifdef _WIN32 return new CriticalSectionWindows(); #else return new CriticalSectionPosix(); #endif }
两个子类负责不同平台下锁的创建工作
class CriticalSectionPosix : public CriticalSectionWrapper { public: CriticalSectionPosix(); virtual ~CriticalSectionPosix(); virtual void Enter(); virtual void Leave(); private: pthread_mutex_t mutex_; friend class ConditionVariablePosix; };
class CriticalSectionWindows : public CriticalSectionWrapper { public: CriticalSectionWindows(); virtual ~CriticalSectionWindows(); virtual void Enter(); virtual void Leave(); private: CRITICAL_SECTION crit; friend class ConditionVariableWindows; };
实现代码很简单就不贴出来了,基本上就是构造函数初始化,析构函数释放,enter和leave分别是加锁和解锁操作。
感觉没有libjingle的talk/base写的简洁,那个采用了另一种思想,通过将类的名字和方法的名字命名一直来达到不同平台调用一致的目的。
以后作为一个库使用吧,它帮我们做了跨平台多好。。。。
简单说一下简单工厂和工厂方法两个模式的不同:
简单工厂模式:
一个工厂方法负责所有对象的创建,当增加新的产品就需要更改上层的工厂方法。可以采用另一种注册的思想:工厂类中维护一个链表,当用户注册了新的产品
加入到链表中,就可以实现增加新的产品,不更改上层抽象层的工作。
工厂方法模式:
将对对象的创建延迟到子类中,由子工厂负责具体产品类的创建
有一个抽象工厂类,且有一个工厂接口,每一个具体工厂都需要实现该接口来创建具体的产品,应用工厂方法通常是创建的产品
是相关的,所有的产品有一个抽象基类,这样抽象工厂的返回值就可以定为抽象产品类指针,供给客户使用。
客户可能需要实例化具体的工厂来创建具体的某一种产品