【工作中学习1】两个设计模式:Singleton(单例)和 Adapter(适配器)

  好久没有写自己的学习小文章,罪过罪过。。最近本菜鸟在项目中接触到经常用到的设计模式,首先是Singleton(单例),这个相信大家都会用到很多,所以自己用代码实现一下,有助于自己学习理解,如有不对,请大家批评指正。

一. Singleton(单例)

  1. 文件:CSingleton.h

 1 #include "stdafx.h"
 2 #include <windows.h>
 3 
 4 class CSingleton{
 5 public:
 6     static CSingleton* Instance()
 7     {
 8         if(m_instance == 0)
 9         {
10             //加锁,防止多线程时多次实例化,破坏单例
11             InitializeCriticalSection(&cs);
12             EnterCriticalSection(&cs);
13 
14             if(m_instance == 0)
15             {
16                 m_instance = new CSingleton();
17             }
18 
19             LeaveCriticalSection(&cs);
20             DeleteCriticalSection(&cs);
21         }
22 
23         return m_instance;
24     }
25     
26     static void CloseSingleton()
27     {
28         if(m_instance)
29         {
30             delete m_instance;
31             m_instance = 0;
32         }
33     }
34 
35     void SetNum(int num)
36     {
37         m_num = num;
38     }
39 
40     int GetNum()
41     {
42         return m_num;
43     }
44 
45 private:
46     CSingleton();
47 
48     ~CSingleton();
49 
50     static CSingleton* m_instance;
51 
52     static CRITICAL_SECTION cs;
53 
54     int m_num;
55 };

  2. 文件:CSingleton.cpp

 1 #include "stdafx.h"
 2 #include "CSingleton.h"
 3 
 4 using namespace std;
 5 
 6 CSingleton* CSingleton::m_instance = 0;
 7 CRITICAL_SECTION CSingleton::cs;
 8 
 9 CSingleton::CSingleton(): m_num(0)
10 {
11     cout << "CSingleton()" << endl;
12 }
13 
14 CSingleton::~CSingleton()
15 {
16     cout << "~CSingleton()" << endl;
17 }

  3. Main函数

 1 #include "stdafx.h"
 2 #include "CSingleton.h"
 3 
 4 using namespace std;
 5 
 6 int _tmain(int argc, _TCHAR* argv[])
 7 {
 8     CSingleton* A = CSingleton::Instance();
 9     
10     A->SetNum(5);
11 
12     CSingleton* B = CSingleton::Instance();    
13 
14     cout << "B->GetNum() = " << B->GetNum() << endl;
15 
16     system("Pause");
17     return 0;
18 }

  4. 程序运行结果:

    值为5,说明指针A,B指向的是同一对象。

  5. 以上就是代码的实现,我觉得自己学习过程中要注意的几点:

    A. 要加锁,防止多线程时多次调用构造函数,破坏单例

    B. 编译时小的问题,不能引用winbase.h,而要用windows.h,否则会编译报错

    C. 要有CloseSingleton()方法,来释放单例的资源。构造函数和析构函数需要都是private。

二. Adapter(适配器)

  这是我在coding过程中遇到的,其实我不能确定是否就是Adapter的模式。主要是解决了一个小问题:

  三个类A,B,C,A是基类,B和C都是A的派生类,这时程序中利用多态特性,A的指针实际指向B或C的对象,来调用方法。

  这时,我需要向B中增加一个方法F,但不能改动C,如果直接在A中增加方法F,因为C也是A的派生类,间接的也改动了C,所以不合适。

  因此,这里增加一个D类,D继承于A,B改为继承于D,由D增加F方法接口,B继承实现此方法F。由此解决这一小问题。

  不确定是否是Adapter的模式(百度百科:Adapter,将一个类的接口变换成客户端所期待的一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作)。

三. 近期小结:

  最近组里任务很多,在coding过程中学习到很多,作为菜鸟,还是要多多总结,哪怕是小问题,小的知识点:-)

Best Regards

Kevin Song

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我杨某人的青春满是悔恨

设计模式之结构型模式(上)

GoF 归纳整理的23个设计模式依据其目的可以分为创建型(Creational)、结构型(Structural)和行为型(Behavioral)三种。关于创建型...

793
来自专栏marsggbo

Flask入门笔记(一)

一、程序的基本结构 1.1 最简单的Flask程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14#coding=utf-8 # 初始化 ...

1828
来自专栏Golang语言社区

GoStub框架使用指南

序言 要写出好的测试代码,必须精通相关的测试框架。对于Golang的程序员来说,至少需要掌握下面四个测试框架: GoConvey GoStub GoMock M...

4467
来自专栏Android开发指南

用最简单的例子说明设计模式(三)之责任链、建造者、适配器、代理模式、享元模式

2595
来自专栏谢易成的专栏

Vue服务端渲染之cookie,user-agent获取

Vue服务端渲染有个参数runInNewContext,之前我们这个参数一直设置为true,这样可以全局获取到直出的context。

2782
来自专栏chenssy

【死磕Sharding-jdbc】---路由&执行

继续以 sharding-jdbc-example-jdbc模块中的 com.dangdang.ddframe.rdb.sharding.example.jdb...

823
来自专栏Danny的专栏

【EJB学习笔记】——有状态的会话Bean和无状态的会话Bean

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

1091
来自专栏大内老A

WCF技术剖析之二十一:WCF基本异常处理模式[下篇]

从FaultContractAttribute的定义我们可以看出,该特性可以在同一个目标对象上面多次应用(AllowMultiple = true)。这也很好理...

1888
来自专栏大数据智能实战

REDIS并行多线程写入时出现“如果基础流不可搜寻,则当读取缓冲区不为空时,将无法写入到 BufferedStream。”解决办法

在并行写入REDIS的时候,有时候会碰到这样的问题,即:  System.NotSupportedException: 如果基础流不可搜寻,则当读取缓冲区不为空...

31510
来自专栏进击的程序猿

raft 系列解读(4) 之 etcd-raft学习

大多数Raft的实现都是整体设计,包括存储处理,消息序列化和网络传输,但是本raft库在实现的时候只实现了最核心的算法,换来了灵活性和性能,网络和disk IO...

874

扫码关注云+社区