Boolan 第十二周 设计模式(二)

2017-04-13  本文已影响0人  wild_horse

设计模式要从类的构建上去理解整个应用的逻辑架构,在正式的软件中可能会遇到,学习这些思想的好办法是通过图形理解逻辑架构,关注点在于稳定(静态部分)的和可扩展的(动态部分)。

Factory Method

实际的Product类和工厂方法都依靠抽象类,扩展的时候只需要再继承一个具体的product和相应的工厂方法,就能够实现的动态地返回相应对象的指针,而不必改变框架。

Abstract Factory

不同于Factory Method,Abstract Factory可以解决一系列相互依赖的对象的创建,通过把这一系列相互依赖的对象的创建工作放在一个抽象类中,可以避免客户程序与一些列对象创建的紧耦合。

Prototype

Prototype提供一个统一的clone接口,返回类对象的拷贝,应对对象不改变的需求。

Builder

把复杂对象构建与表示分类(标准库string的实现),所以主程序能适应新子类的扩展。

class Singleton{
private:
    Singleton();
    Singleton(const Singleton& other);
public:
    static Singleton* getInstance();
    static Singleton* m_instance;
};
Singleton* Singleton::m_instance=nullptr;
//双检查锁,但由于内存读写reorder不安全
Singleton* Singleton::getInstance() {
    
    if(m_instance==nullptr){
        Lock lock;
        if (m_instance == nullptr) {
            m_instance = new Singleton();  //reorder 可能先返回指针,再构造
        }
    }
    return m_instance;
}

单例模式返回一个单例对象,进行双检查锁,因为在第一个判断时,若有几个线程同时进入,在第一线程的完成后,Lock失效(作用域),若是

//单检查锁
   if(m_instance==nullptr){
        Lock lock;
            m_instance = new Singleton(); 
        }

又重新生成单例对象,所以必须使用双检查锁。
但是双检查锁由于内存读写reorder不安全,reorder是对象构建时 分配内存->构造对象->返回指针,被优化为分配内存->直接返回指针->再构建对象,这样在 返回指针的同时,其他线程对 指针判断时,以为构建对象的工作完成,直接跳转到最后的return语句,出现错误(实际对象构建还未完成)。

Singleton* Singleton::getInstance() {

  if(m_instance==nullptr){//2. 同一时间判断
      Lock lock;
      if (m_instance == nullptr) {
          m_instance = new Singleton();  //1. reorder返回指针
      }
  }
  return m_instance;//3. 在对象构建完成之前返回了
}
上一篇下一篇

猜你喜欢

热点阅读