C++中的一些设计模式

C++中的一些设计模式

这题超纲了 柳筋

前言

今天来学习一下C++的一些设计模式,本人只学了几个,甚至于我只用过一个,但这不妨碍我去理解这些设计模式,其他的设计模式以后会慢慢补充哒,废话不多说,直接来吧!

设计模式

设计模式(英语 design pattern)是对面向对象设计中反复出现的问题的解决方案

这个术语是在1990年代由Erich Gamma等人从建筑设计领域引入到计算机科学中来的。这个术语的含义还存有争议。算法不是设计模式,因为算法致力于解决问题而非设计问题。设计模式通常描述了一组相互紧密作用的类与对象。设计模式提供一种讨论软件设计的公共语言,使得熟练设计者的设计经验可以被初学者和其他设计者掌握。设计模式还为软件重构提供了目标

随着软件开发社群对设计模式的兴趣日益增长,已经出版了一些相关的专著,定期召开相应的研讨会,而且Ward Cunningham为此发明了WikiWiki用来交流设计模式的经验。

总之,设计模式就是为了解决某类重复出现的问题而出现的一套成功或有效的解决方案

单例模式

在烂大街的WebServer项目中,我们经常利用单例模式来创建对象,日志数据库连接池等等这种只需要一个对象的情况下,我们就可以使用单例模式来创建对象

什么是单例模式

单例模式就是指在内存中只会创建且仅创建一个对象的设计模式。当我们在程序中多次使用同一个对象且作用相同时(比如日志对象,我们总是往里面写入数据),为了防止频繁的创建对象而使得内存飙升,我们就可以使用单例模式只创建一个对象,所有程序都是用这一个对象

单例模式的类型
  1. 懒汉模式:顾名思义,就是在程序需要使用这个对象的时候才创建
  2. 饿汉模式:当类加载的时候,无论该程序中是否会需要使用到该对象,都会创建,就像一个很饿的人,总是想快点吃
懒汉模式

懒汉式创建对象的方法是在**程序使用对象前,先判断该对象是否已经实例化(判空)**,若已实例化直接返回该类对象,否则则先执行实例化操作

在写懒汉模式的单例时,我们需要注意以下几个点:

  1. 全局只有一个实例
    我们知道,在C++中,如果我们给类中的成员变量加上static关键字后,那么该成员变量就会变成全局唯一的静态变量,所有通过该类创建出来的实例都共享同一个变量,并且静态成员变量需要在类外进行初始化
  2. 将类的构造函数私有化,为的就是不让其他程序利用构造函数重新构造一个新的实例
  3. 静止赋值和拷贝,所以需要将默认拷贝函数也delete掉
  4. 用户只能通过类中的成员函数获取唯一实例,由于实例为静态成员变量,所以获取函数必须也是静态成员函数,因为只有静态成员函数才能获取静态成员变量

以下是一个有缺陷但逻辑是对的懒汉模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class single
{
public:
//获取唯一实例
static single *GetInstance();
private:
static single *p; //私有静态指针变量指向唯一实例
single(){}; //私有化构造函数
~single(){}; //私有化析构函数
single& operator=(const single&)=delete; //进制拷贝函数
};

single* single::p=NULL; //类外初始化静态变量
single* single::GetInstance()
{
//如果实例没创建
if(p==NULL)
{
p=new single(); //创建实例
}
return p;
}

上面的函数在单线程的时候是没有问题的,但是在多线程的时候就出现问题了,也就是老生常谈的线程安全问题,当有三个线程都掉了GetInstance函数的时候,就会创建出三个实例,这是不符合单例模式的定义的,那么如何解决这个问题呢?还是利用很经典的互斥锁

以下是修改完的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class single
{
public:
//获取唯一实例
static single *GetInstance();
//互斥锁,静态锁是因为静态函数只能访问静态变量
static pthread_t mutex;
private:
static single *p; //私有静态指针变量指向唯一实例
single(){}; //私有化构造函数
~single(){}; //私有化析构函数
single& operator=(const single&)=delete; //进制拷贝函数
};

single* single::p=NULL; //类外初始化静态变量
single* single::GetInstance()
{
//上锁
pthread_mutex_lock(&mutex);

//如果实例没创建
if(p==NULL)
{
p=new single(); //创建实例
}

//解锁
pthread_mutex_unlock(&mutex);
return p;
}

但是这样也有一个问题,那就是每次调用都要上锁,但事实上,只要创建好了单例,那么其余线程都会满足p==NULL,所以我们再做一次更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class single
{
public:
//获取唯一实例
static single *GetInstance();
//互斥锁,静态锁是因为静态函数只能访问静态变量
static pthread_t mutex;
private:
static single *p; //私有静态指针变量指向唯一实例
single(){}; //私有化构造函数
~single(){}; //私有化析构函数
single& operator=(const single&)=delete; //进制拷贝函数
};

single* single::p=NULL; //类外初始化静态变量
single* single::GetInstance()
{
//如果实例没创建
if(p==NULL)
{
//上锁
pthread_mutex_lock(&mutex);

if(p==NULL)
{
p=new single(); //创建实例
}

//解锁
pthread_mutex_unlock(&mutex);
}
return p;
}
饿汉模式

懒汉模式不同,懒汉模式只有在用户调用GetInstance函数的时候,才会去判断并且创建,而饿汉模式则是当我们类编译的时候,就进行单例的创建,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class single
{
public:
static single* GetInstance();
private:
static single *p;
single(){};
~single(){};
};

single* single::p=new single(); //直接创建单例
single* single::GetInstance()
{
return p;
}

饿汉模式虽好,但其存在隐藏的问题,在于非静态对象(函数外的static对象)在不同编译单元中的初始化顺序是未定义的。如果在初始化完成之前调用 GetInstance()函数会返回一个未定义的实例

工厂模式

当我们在一个程序中定义了很多类的时候,如果我们频繁的去创建不同的类对象的时候骂我们需要一直new对象,这是很不利于我们后期对代码的维护的,那么有没有一种方法,就是可以自动帮我们创建类对象呢?

来了!它来了!工厂模式就是设计来帮我们解决这个问题的

什么是工厂模式

很简单,举个例子,在海贼王中存在着一个人造恶魔果实(smile果实)制造工厂,当我们想要什么样的恶魔果实,我们告诉工厂就行了,具体如何去创造就是工厂的事情了,不需要我们去关心,这就是工厂模式。利用工厂模式,我们可以不用关心对象的创作过程,我们只需要关心对象的实际操作,也就是说,工厂模式帮助我们分离了对象的创建和使用,方便后期的维护和扩展.

工厂模式也分为三种:

  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式

简单工厂模式

简单工厂模式(Simple Factory Pattern)专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类

  1. Factory工厂角色(工厂类):
    工厂角色即工厂类,是简单工厂模式的核心,负责创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需要的产品对象
  2. Product(抽象产品角色):
    抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公告接口。所创建的具体产品对象都是其子类对象
  3. ConcreteProduct(具体产品角色):
    具体产品角色是简单工厂模式的创建目标。每个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的方法
    ProductA、ProductB和ProductC继承自Product虚拟类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC,Factory根据不同的条件创建不同的Product对象
    简单工厂的实现

    我们以电视机的栗子来说吧
    有一个工厂,它专门就是用来生产电视机的,但我们知道,电视机有很多牌子,不同的牌子价格和质量也是不同的
    如下图所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #include <iostream>
    #include <vector>
    using namespace std;

    typedef enum ProductTypeTag
    {
    Hair,
    Hisense,
    }PRODUCTTYPE;

    //抽象产品类 TV(电视机类)
    class TV
    {
    public:
    virtual void Show() = 0;
    virtual ~TV(){};//声明析构函数为虚函数,防止内存泄漏
    };
    //具体产品类 HairTV(海尔电视类)
    class HairTV : public TV
    {
    public:
    void Show()
    {
    cout<<"I'm HairTV "<<endl;
    }
    };
    //具体产品类 HisenseTV(海信电视类)
    class HisenseTV : public TV
    {
    public:
    void Show()
    {
    cout<<"I'm HisenseTV"<<endl;
    }
    };


    // 工厂类 TVFactory(电视机工厂类)
    class TVFactory
    {
    public:
    TV* CreateTV(PRODUCTTYPE type)
    {
    switch (type)
    {
    case Hair:
    return new HairTV();

    case Hisense:
    return new HisenseTV();
    default:
    return NULL;
    }
    }
    };

    int main(int argc, char *argv[])
    {
    // 创建工厂类对象
    TVFactory* myTVFactory = new TVFactory();
    TV* hairTV = myTVFactory->CreateTV(Hair);
    if (hairTV != NULL)
    hairTV->Show();

    TV* hisenseTV = myTVFactory->CreateTV(Hisense);
    if (hisenseTV != NULL)
    hisenseTV->Show();

    delete myTVFactory;
    myTVFactory = NULL;

    delete hairTV;
    hairTV = NULL;

    delete hisenseTV;
    hisenseTV = NULL;

    return 0;
    }
优势

本着高内聚低耦合的原则,将系统的逻辑部分和功能分开

劣势

就拿上面的栗子来说吧,当我们想要生产派大星牌电视机的时候,我们就需要在工厂里面加入对派大星牌电视机的生产,但其实这就违背了我们设计模式中的一个开闭原则

开闭原则:

  1. 开放封闭原则(OCP,Open For Extension, Closed For Modification Principle)
  2. 类的改动是通过增加代码进行的,而不是修改源代码
  3. 说的是代码扩展性问题——对扩展开放,对修改关闭(封闭)

开闭原则详细的解释:当增加新功能,不应该通过修改已经存在的代码来进行,而是应该通过扩展代码(比如增加新类,增加新成员函数)来进行

而当我们增加一个新的类时候,就需要对已经存在的工厂代码进行修改,而这就违背了这个原则

工厂方法模式

既然简单工厂模式违背了开闭原则,那么我们就在它的基础上做一些修改,使得改模式即保留了简单工厂模式的优点,又解决了它的缺点,而这,就是工厂方法模式

工厂方法模式

在工厂模式中,工厂父类负责定义创建产品对象的公告接口,而工厂子类负责生成具体的产品对象。
目的是将产品的实例化操作延迟到工厂子类中完成,通过工厂子类来确定究竟应该实例化哪一个具体产品类

  1. Product(抽象产品)
    抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,也是产品对象的共同父类或接口

  2. ConcreteProduct(具体产品)
    具体产品实现了抽象产品的接口,某种类型的具体产品由专门的具体工厂创建

  3. Factory(抽象工厂)

  4. ConcreteFactory(具体工厂)

具体工厂是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户调用,返回一个具体产品类的实例

简单工厂的实现

还是继续上面的栗子
工厂方法模式,将原有的工厂进行分割,为每种品牌的电视机提供一个子工厂,海尔工厂专门负责生产海尔电视机,海信工厂专门负责生产海信电视机,若增加派大星电视,只需要增加一个新的派大星工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{% asset_img 工厂模式1.jpg 工厂模式 %}
#include <iostream>
#include <vector>
using namespace std;

//抽象产品类 TV(电视机类)
class TV
{
public:
virtual void Show() = 0;
virtual ~TV(){};//声明析构函数为虚函数,防止内存泄漏
};
//具体产品类 HairTV(海尔电视类)
class HairTV : public TV
{
public:
void Show()
{
cout<<"I'm HairTV "<<endl;
}
};
//具体产品类 HisenseTV(海信电视类)
class HisenseTV : public TV
{
public:
void Show()
{
cout<<"I'm HisenseTV"<<endl;
}
};

//抽象工厂类
class TVFactory
{
public:
virtual TV *Create()=0;
virtual ~TVFactory();
};

//具体工厂类 海尔电视子工厂
class HairFactory::public TVFactory
{
public:
TV *Create()
{
return new HairTV();
}
}

//具体工厂类 海信电视子工厂
class HisenseFactory::public TVFactory
{
public:
TV* Create()
{
return new HisenseFactory();
}
}

int main(int argc , char *argv [])
{
TVFactory *hairTVFactory = new HairTVFactory();
TV *hairTV = hairTVFactory->CreateTV();
hairTV->Show();

TVFactory *hisenseTVFactory = new HisenseTVFactory();
TV *hisenseTV = hisenseTVFactory->CreateTV();
hisenseTV->Show();

if (hairTVFactory!= NULL)
{
delete hairTVFactory;
hairTVFactory = NULL;
}

if (hairTV != NULL)
{
delete hairTV;
hairTV = NULL;
}

if (hisenseTVFactory != NULL)
{
delete hisenseTVFactory;
hisenseTVFactory = NULL;
}

if (hisenseTV != NULL)
{
delete hisenseTV;
hisenseTV = NULL;
}
return 0;
}

当我们想要生产派大星电视机的时候,只需要加一个工厂和一个具体的派大星电视机类就好,而无需在原本的代码上进行修改

抽象工厂模式

抽象工厂模式是工厂方法模式的泛化版,工厂模式是一种特殊的抽象工厂模式,在工厂模式中,每个具体工厂只能生产一种具体的产品,如海尔电视机厂只生产海尔电视机,而抽象工厂方法模式中,一个具体的工厂可以生产多个具体产品

  1. AbstractFactory(抽象工厂)
    抽象工厂用于声明生成抽象产品的方法,在一个抽象工厂中可以定义一组方法,每一个方法对应一个产品等级结构
  2. ConcreteFactory(具体工厂)
    具体工厂实现了抽象工厂声明的抽象产品的方法,生成一组具体产品
  3. AbstractProduct(抽象产品)
    抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法
  4. ConcreteProdunct(具体产品)
    抽象工厂实现

    还是上面的栗子,我们知道,海尔公司不光生产电视,它还生产空调之类的,tcl也是

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    #include <iostream>
    using namespace std;

    // 抽象产品类类 Television(电视机类)
    class Television
    {
    public:
    virtual void Show() = 0;
    virtual ~Television(){};//析构函数声明为虚函数,防止内存泄漏
    };

    //具体产品类 HaierTelevision(海尔电视机类)
    class HaierTelevision : public Television
    {
    public:
    void Show()
    {
    cout << "I'm HaierTelevision" << endl;
    }
    };
    //具体产品类 TCLTelevision(TCL电视机类)
    class TCLTelevision : public Television
    {
    public:
    void Show()
    {
    cout << "I'm TCLTelevision" << endl;
    }
    };

    // 抽象产品类 AirCondition(空调类)
    class AirCondition
    {
    public:
    virtual void Show() = 0;
    virtual ~AirCondition(){};//析构函数声明为虚函数,防止内存泄漏
    };
    //具体产品类 HairAirCondition(海尔空调类)
    class HairAirCondition : public AirCondition
    {
    public:
    void Show()
    {
    cout << "I'm HairAirCondition" << endl;
    }
    };
    //具体产品类 TCLAirCondition(TCL空调类)
    class TCLAirCondition : public AirCondition
    {
    public:
    void Show()
    {
    cout << "I'm TCLAirCondition" << endl;
    }
    };

    // 抽象工厂类 EFactory(电器工厂类)
    class EFactory
    {
    public:
    virtual Television* CreateTelevision() = 0;
    virtual AirCondition* CreateAirCondition() = 0;
    virtual ~EFactory(){};//析构函数声明为虚函数,防止内存泄漏
    };
    //具体工厂类 HairFactory(海尔工厂类)
    class HairFactory : public EFactory
    {
    public:
    Television* CreateTelevision()
    {
    return new HaierTelevision();
    }

    AirCondition* CreateAirCondition()
    {
    return new HairAirCondition();
    }
    };
    //具体工厂类 TCLFactory(TCL工厂类)
    class TCLFactory : public EFactory
    {
    public:
    Television* CreateTelevision()
    {
    return new TCLTelevision();
    }

    AirCondition* CreateAirCondition()
    {
    return new TCLAirCondition();
    }
    };

    int main(int argc, char *argv[])
    {
    EFactory *hairFactory = new HairFactory ();/*实例化工厂抽象类*/
    Television *haierTelevision =hairFactory->CreateTelevision();/*实例化产品抽象类*/
    AirCondition *haierAirCondition = hairFactory->CreateAirCondition();

    haierTelevision->Show();
    haierAirCondition->Show();

    EFactory *tCLFactory = new TCLFactory ();
    Television *tCLTelevision = tCLFactory->CreateTelevision();
    AirCondition *tCLAirCondition = tCLFactory->CreateAirCondition();

    tCLTelevision->Show();
    tCLAirCondition->Show();

    if (hairFactory != NULL)
    {
    delete hairFactory;
    hairFactory = NULL;
    }

    if (haierTelevision != NULL)
    {
    delete haierTelevision;
    haierTelevision= NULL;
    }

    if (tCLAirCondition != NULL)
    {
    delete tCLAirCondition;
    tCLAirCondition = NULL;
    }

    if (tCLFactory != NULL)
    {
    delete tCLFactory;
    tCLFactory= NULL;
    }

    if (tCLTelevision != NULL)
    {
    delete tCLTelevision;
    tCLTelevision = NULL;
    }

    if (tCLAirCondition != NULL)
    {
    delete tCLAirCondition;
    tCLAirCondition = NULL;
    }
    }
优点
  1. 抽象工厂模式将产品族的依赖与约束关系放到抽象工厂中,便于管理
  2. 职责解耦,用户不需要关心一堆自己不关心的细节,由抽象工厂来负责组件的创建
  3. 切换产品族容易,只需要增加一个具体工厂实现,客户端选择另一个套餐就可以了
优点
  1. 抽象工厂模式类增加的速度很快,有一个产品族就需要增加一个具体工厂实现,比较繁琐
  2. 产品族难以扩展产品。当产品族中增加一个产品时,抽象工厂接口中需要增加一个函数,对应的所有具体工厂实现都需要修改,修改放大严重
  3. 抽象工厂并未完全屏蔽创建细节,给出的都是组件。对于这种情况可以结合工厂模式或简单工厂模式一起使用

观察者模式

观察者模式又叫做发布-订阅模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动的更新自己。

或许观看以下实例或更清楚点(结构上图)

观察者模式的实现
Head.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#ifndef HEAD_H
#define HEAD_H

#include <iostream>
#include <string>
#include <list>
using namespace std;

//抽象观察者,为所有的具体观察者定义一个接口,在当主题更新的时候更新自己
class Observer;

//对所有观察者的集合,每一个主题都可以有很多个观察者,利用list双向链表将观察者保存起来,方便后面的更新
class Subject{

public:
void attach(Observer *observer); //加入新的观察者
void detach(Observer *observer); //删除观察者
void notify(); //调用该函数,可以开始对list里面的每个观察者进行更新操作,但这个函数并不直接更新数据,只起到了一个通知作用,真正用来更新数据的函数在观察者自己的类中
~Subject();

private:
list<Observer*> observers; //双向链表,存储观察者
};


class Observer{

public:
virtual void update(){} //抽象更新函数,具体实现由具体观察者来实现
virtual string getName(){ return ""; } //获取具体观察者的名字,为抽象函数,在具体观察者实现

};

//具体主题
class ConcreteSubject : public Subject{

public:
string getSubjectState(); //获取具体主题的状态
void setSubjectState(const string &str); //将有关状态存入具体观察者对象,当具体主题的状态发生改变的时候,通知所有登记过的观察者

private:
string subjectState;
};

//具体观察者
class ConcreteObserver : public Observer{

public:
ConcreteObserver(ConcreteSubject *subject, string name);
void update(); //更新操作
string getName();

private:
string name; //观察者名字
string observerState; //观察者状态
ConcreteSubject *subject; //观察者对应的具体主题
};

#endif //HEAD_H
Head.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "Head.h"

//将观察者插入观察者队列
void Subject::attach(Observer *observer)
{
observers.push_back(observer);
}

//从观察者队列中删除观察者
void Subject::detach(Observer *observer)
{
observers.remove(observer);
}


void Subject::notify()
{
list<Observer*>::iterator it = observers.begin();
//循环队列里的观察者,并让他们执行更新操作
while(it != observers.end()){

(*it)->update();
it++;
}
}


Subject::~Subject()
{
cout << "开始析构了" << endl;

list<Observer*>::iterator it = observers.begin();
while(it != observers.end()){

cout << "开始删除: " << (*it)->getName() << endl;
delete *it;
it++;
}
observers.clear();
}

//获取主题当前状态
std::string ConcreteSubject::getSubjectState()
{
return subjectState;
}

//设置主题状态
void ConcreteSubject::setSubjectState(const string &str)
{
subjectState = str;
}

ConcreteObserver::ConcreteObserver(ConcreteSubject *subject, string name)
{
this->subject = subject;
this->name = name;
}

//观察者更新操作
void ConcreteObserver::update()
{
observerState = subject->getSubjectState();
cout << "发布者更新东西了 !!! 订阅者:" << name << " 状态:" << observerState << endl;
}

std::string ConcreteObserver::getName()
{
return name;
}
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "Head.h"

int main(int *argc, int *argv[]){

ConcreteSubject *subject = new ConcreteSubject;

subject->attach(new ConcreteObserver(subject, "第一个粉丝"));
subject->attach(new ConcreteObserver(subject, "第二个粉丝"));
subject->attach(new ConcreteObserver(subject, "第三个粉丝"));

subject->setSubjectState("Hello");
subject->notify();

cout << "----------- 华 丽 的 分 割 线 -----------" << endl;
subject->attach(new ConcreteObserver(subject, "王二麻子"));
subject->setSubjectState("呵呵");
subject->notify();

cout << endl;
delete subject;

getchar();
return 0;
}
  1. 服务器发布新版本,让客户端更新
  2. 游戏群发邮件给补贴等
  3. 聊天室系统

都可以很好的套用这种模式

结语

鼠鼠终于!终于又收到了一个面试!虽然不是大厂的,但聊胜于无啊,希望今晚能顺利叭,写完了这篇博客就要看八股去咯,祝好运~

  • 标题: C++中的一些设计模式
  • 作者: 这题超纲了
  • 创建于: 2023-03-10 13:30:59
  • 更新于: 2023-06-23 14:39:36
  • 链接: https://qx-gg.github.io/2023/03/10/blog11/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
推荐阅读
C++的继承、封装和多态 C++的继承、封装和多态 浙江宇视科技一面 浙江宇视科技一面 关于线程池的构建及理解 关于线程池的构建及理解
 评论