设计模式之二

1 单例模式:

很多人看到单例,马上就激动了,这题我会!
然后就是在静态全局区new了一个对象,其实单例模式存在很多陷阱。
定义:

证一个类仅有一个实例,并提供一个访问它的全局访问点。

注意点:

  1. 构造,虚构,拷贝构造,赋值重载等这些需要放到私有成员当中,防止外部访问;
  2. 静态成员变量,需要初始化;
  3. 退出时是否正确释放,需要在private,增加静态释放函数。

多线程问题:

  1. 线程安全问题,当存在多线程访问时需要考虑,锁是一种方案。但是要注意一点就是锁的位置
//这里加锁会影响效率
if(_instance == NULL)
{
	lock(m_mutex);
	//这里加锁需要考虑多次new的问题,造成野指针。
	if(_instance == NULL)
	{
		_instance = new Single;
	}
}

CPU reorder问题
cpu优化后,仍然有可能造成多次new的问题,这时候需要引入内存原子操作,来保证内存分配的正确性,这种方法显然太复杂。

终极解决方案
这个方案是effective提出的方案,很好解决上述的问题。具体代码如下,膜拜大佬!

//主要原理是
//1. c++11 magic static特性:当多线程初始化同一个变量,并发同时进入声明语句,会阻塞等待初始化结束。
//2. 局部变量退出时,系统会自我调用析构回收内存。
//3. 静态对象初始化没有new的cpu reorder问题; 
Singleton 
{
public: 
    static Singleton& GetInstance() 
    { 
        static Singleton instance; 
        return instance; 
    } 
private: 
    Singleton(){};
    ~Singleton() {};
    Singleton(const Singleton&) {};
    Singleton& operator=(const Singleton&) {}; 
};

2 工厂模式

定义:

定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。

要点:

  • 抽象工厂类不会负责所有产品的创建,仅负责给出具体工厂类必须实现的接口,具体产品的创建由具体工厂类去实现。
  • 一般用于类的创建比较多复杂操作,包括参数多样,初始化复杂等等。
  • 另一种情况是创建的类依赖关系太复杂,这时候也需要对外屏蔽这些细节

3 抽象工厂模式

定义:

提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。

要点

  • 基本和工厂模式相同,只是将相关操作封装到同一个接口类进行操作。

4 责任链模式

定义:

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成
一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

要点:

  • 责任链模式主要用于处理审批流程这种模式,数据流到有人处理位置。
  • 责任链要点是固定处理的算法骨架,就是先判断是否可以处理,能处理就处理;不能处理就交给下一个对象处理。数据在两条中流动直到被处理为止。
  • 这也是一种依赖导致的案例,基类负责实现算法骨架,子类实现自己的处理流程。最终数据从链条起始位置流入。

5 装饰器模式

定义
动态地给一个对象添加一些额外的职责,给一个对象增加一些新的功能,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。
要点:

  • 装饰器的基类组合自己的指针;
  • 装饰对象实现相同的接口,同时利用被传入对象的数据进行增加一些额外修饰。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值