设计模式----持续学习更新中

  • 类图介绍
    • 类图中各个要点:
      • 属性标识:
      • 类关系介绍
        • 依赖
        • 关联:
        • 聚合
        • 组合
        • 实现
        • 继承
  • 创建型模式
    • 1、简单工厂模式
      • 介绍
      • 类图
      • 结构代码
      • 测试代码
  • 2、工厂模式
    • 介绍
    • 类图
    • 结构代码
    • 测试代码
  • 3、抽象工厂模式
    • 介绍
    • 类图
    • 结构代码
    • 测试代码
  • 4、建造者模式
    • 介绍
    • 类图
    • 结构代码
    • 测试代码
  • 5、原型模式
    • 介绍
    • 类图
    • 结构代码
    • 测试代码
  • 6、单例模式
    • 介绍
    • 类图
    • 结构代码
    • 测试代码
  • 7、代理模式
    • 介绍
    • 类图
    • 结构代码
    • 测试代码
  • 8、装饰者模式
    • 介绍
    • 类图
    • 结构代码
    • 测试代码

学习总结,文章内容学自:添加链接描述

类图介绍

类图由Enterprice Architect创建,安装包:
链接: https://pan.baidu.com/s/1JmGMowYxep4whIor-boQlw
提取码:cxkm

类图中各个要点:

属性标识:

+:public
-:private
#:protect
~:defualt,可省略不写
字段和方法返回值的类型非必须
抽象类或抽象方法用斜体表示
静态类或静态方法加下划线
如果是接口在类名上方加<>(不过在C++中只有抽象类,没有接口这一定义)

类关系介绍

依赖

一个类A使用到了另一个类B,但是这种使用关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A,通常,类B作为类A的方法的参数(或者局部变量)存在。
UML图表示:虚线加箭头,箭头表示被依赖,起始为依赖

关联:

关联体现的是两个类之间语义级别的一种强依赖关系,比如关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。
方向性(代表一个类是否拥有能够导航到另外一个类的知识,比如导师与学生之间的关系是属于双向关联;学生与课程之间的关系是属于单向关联)
UML图表示:带箭头的实线,箭头指向被关联类,实线起始端是关联类。

聚合

组合和聚合都是讨论一个类由其他类构成的情况,是一种整体和部分的关系。聚合相较于组合,关系要弱一些,但也是整体和部分的关系,并非同生共死,部分实例可以添加到聚合整体,也可以从聚合整体中移出。比如大学里的学院,其部分包括:管理办公室、系和研究中心,系可以创建和撤销,研究中心也可以独立于学院而存在。
UML图表示:实线加空心棱形,起始端为个体类,菱形端为群体类

组合

组合和聚合都是讨论一个类由其他类构成的情况,是一种整体和部分的关系。组合是一种很强的关系,部分对象的创建、存在、和消亡都是和整体一起的,所谓同生共死的关系,比如ATM机由读卡器、吐钞器、凭条打印等组成,他们就构成一个组合关系,创建一个ATM机类对象,就必须构造读卡器对象。
UML图表示:实线加实心棱形,起始端为部分,菱形端为整体

实现

实现关系用于定义接口和实现接口的类间关系。如果几个类对外处理的结果是一致的,但得到这种结果的方式不一样,此时就可以定义一个统一的接口,让这几个类都以自己的方式来实现,我们称这种方式为接口处理。所以,接口由子类自定义实现的过程就体现了一种“实现”关系。
UML图表示:虚线加空心箭头

继承

一个类(子类、子接口)继承另外的一个类(父类、父接口)的功能,并可以增加它自己的新功能的能力,如果几个类存在部分相同功能,此时就可以抽象出一个父类来,将相同的部分由父类实现,让他们都继承这个类。继承是通过部分相同的功能,实现不同的结果。
UML图表示:实线加空心箭头

创建型模式

1、简单工厂模式

介绍

功能:定义一个简单工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
角色:
工厂(Factory):根据客户提供的具体产品类的参数,创建具体产品实例
抽象产品(AbstractProduct):具体产品类的基类,包含创建产品的公共方法
具体产品(ConcreteProduct):抽象产品的派生类,包含具体产品特有的实现方法,是简单工厂模式的创建目标
优点:
1、工厂类提供创建具体产品的方法,并包含一定判断逻辑,客户不必参与产品的创建过程
2、客户只需要知道对应产品的参数即可,参数一般简单好记,如数字、字符或者字符串等

缺点:
简单工厂模式在想要其他产品的时候,需要从抽象产品类派生一个具体的产品类,并且在工厂中添加生成该产品的分支条件。违背了开闭原则(对扩展开放,对修改关闭),即在扩展功能的时候修改了既有的代码。另一方面,简单工厂模式所有的判断逻辑都在工厂类中实现,一旦工厂类设计故障,则整个系统都受影响。

类图

结构代码

#ifndef _SIMPLE_FACTORY_
#define _SIMPLE_FACTORY_#include <iostream>//抽象产品类AbstractProduct
class AbstractSportProduct
{public:AbstractSportProduct() {}virtual ~AbstractSportProduct() {};//抽象方法virtual void printName() = 0;virtual void play() = 0;
};//具体产品类Basketball
class Basketball :public AbstractSportProduct
{public:Basketball(){printf("get Basketball!!!\n");//play();}~Basketball() {printf("release Basketball!!!\n");}//具体实现方法void printName(){printf("I'm Basketball!!!\n");}void play(){printf("play Basketball!!!\n");}
};//具体产品类Football
class Football :public AbstractSportProduct
{public:Football(){printf("get football!!!\n");//play();}~Football(){printf("release football!!!\n");}//具体实现方法void printName(){printf("I'm football\n");}void play(){printf("play football!!!\n");}
};//具体产品类Volleyball
class Volleyball :public AbstractSportProduct
{public:Volleyball(){printf("get volleyball!!!\n");//play();}~Volleyball(){printf("release volleyball!!!\n");}//具体实现方法void printName(){printf("I'm volleyball\n");}void play(){printf("play volleyball!!!\n");}
};//具体产品类pingpang
class Pingpang :public AbstractSportProduct
{public:Pingpang(){printf("get pingpang!!!\n");}~Pingpang(){printf("release pingpang!!!\n");}//具体实现方法void printName(){printf("I'm pingpang\n");}void play(){printf("play pingpang!!!\n");}
};class Factory
{public:std::shared_ptr<AbstractSportProduct> getSportProduct(std::string productName){std::shared_ptr<AbstractSportProduct> ptr;if (productName == "Basketball"){//ptr = std::shared_ptr<AbstractSportProduct>(new Basketball());ptr = std::make_shared<Basketball>();}else if (productName == "Football"){ptr = std::shared_ptr<AbstractSportProduct>(new Football);}else if (productName=="Volleyball"){ptr = std::make_shared<Volleyball>();}else if (productName == "Pingpang"){ptr = std::make_shared<Pingpang>();}return ptr;}};#endif

测试代码

#include<stdlib.h>
#include<iostream>
#include "SimpleFactory.h"using namespace std;int main()
{shared_ptr<Factory> factory=make_shared<Factory>();//负责生成产品的工厂shared_ptr<AbstractSportProduct> ptr;//产品指针ptr = factory->getSportProduct("Football");ptr = factory->getSportProduct("Pingpang");ptr = factory->getSportProduct("Basketball");ptr = factory->getSportProduct("Volleyball");//以下为测试部分shared_ptr<AbstractSportProduct> ptr1,ptr2;//产品指针ptr1 = factory->getSportProduct("Football");ptr2 = factory->getSportProduct("Volleyball");ptr1->printName();ptr2->printName();swap<AbstractSportProduct>(ptr1,ptr2);//交换指针指向的产品ptr1->printName();ptr2->printName();(*ptr1).play();(*ptr2).play();ptr1 = ptr2;ptr1->printName();ptr2->printName();cout << ptr1.unique() << endl;//该指针是否单独指向一个对象cout << ptr1.use_count() << endl;//返回指针指向对象的共享指针的数量return 0;
}

2、工厂模式

介绍

功能:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
角色:
抽象工厂:所有生产具体产品的工厂类的基类,提供工厂类的公共方法
具体工厂:生产具体的产品
抽象产品:所有产品的基类,提供产品类的公共方法
具体产品:具体的产品类
优点:
1、工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂
2、工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键
3、新加入产品时,无需修改原有的代码,增强了系统的可扩展性,符合开闭原则
缺点:
1、添加新产品时需要同时添加新的产品工厂,系统中的类数量成对增加,增加了系统的复杂度,更多的类需要编译和运行,增加了系统的额外开销
2、工厂和产品都引入了抽象层,客户端代码中均使用的抽象层(AbstractFactory和AbstractSportProduct),增加了系统的抽象层次和理解难度。

使用环境:
客户端不需要知道他所需要创建的对象的类
抽象工厂类通过其子类来指定创建哪个对象

类图

结构代码

#ifndef _FACTORY_METHOD_
#define _FACTORY_METHOD_#include<iostream>
#include<string>
using namespace std;//抽象产品类AbstractProduct
class AbstractSportProduct
{public:AbstractSportProduct() {}virtual ~AbstractSportProduct() {}//抽象方法virtual void printName() = 0;virtual void play() = 0;
};//具体产品类Basketball
class Basketball :public AbstractSportProduct
{public:Basketball(){cout << "get basketball" << endl;}~Basketball(){cout << "release basketball" << endl;}//实现方法void printName(){cout << "I'm basketball" << endl;}void play(){cout << "play basketball" << endl;}
};//具体产品类Football
class Football :public AbstractSportProduct
{public:Football(){cout << "get football" << endl;}~Football(){cout << "release football" << endl;}//实现方法void printName(){cout << "I'm football" << endl;}void play(){cout << "play football" << endl;}
};//具体产品类Volleyball
class Volleyball :public AbstractSportProduct
{public:Volleyball(){cout << "get volleyball" << endl;}~Volleyball(){cout << "release volleyball" << endl;}//实现方法void printName(){cout << "I'm volleyball" << endl;}void play(){cout << "paly volleyball" << endl;}
};//抽象工厂类
class AbstractFactory
{public:virtual ~AbstractFactory() {}virtual AbstractSportProduct *getSportProduct() = 0;
};//具体工厂类BasketballFactory
class BasketballFactory :public AbstractFactory
{public:BasketballFactory(){cout << "get basketballfactory" << endl;}~BasketballFactory(){cout << "release basketballfactory" << endl;}//实现获取产品方法AbstractSportProduct *getSportProduct(){return new Basketball();}
};//具体工厂类FootballFactory
class FootballFactory :public AbstractFactory
{public:FootballFactory(){cout << "get footballfactory" << endl;}~FootballFactory(){cout << "release footballbasketball" << endl;}//实现获取产品的方法AbstractSportProduct *getSportProduct(){return new Football();}
};//具体工厂类VolleyballFactory
class VolleyballFactory :public AbstractFactory
{public:VolleyballFactory(){cout << "get volleyballfactory" << endl;}~VolleyballFactory(){cout << "release volleyballfactory" << endl;}//实现获取具体产品的方法AbstractSportProduct *getSportProduct(){return new Volleyball();}
};#endif

测试代码


#include<iostream>
#include<string>
#include "FactoryMethod.h"using namespace std;int main()
{AbstractFactory* fac1 = new BasketballFactory();AbstractFactory* fac2 = new FootballFactory();AbstractFactory* fac3 = new VolleyballFactory();AbstractSportProduct *basketball = fac1->getSportProduct();AbstractSportProduct *football = fac2->getSportProduct();AbstractSportProduct *volleyball = fac3->getSportProduct();basketball->printName();football->printName();volleyball->printName();basketball->play();football->play();volleyball->play();return 0;}

3、抽象工厂模式

介绍

功能:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
角色:
抽象工厂:所有生产具体产品的工厂类的基类,提供工厂类的公共方法
具体工厂:生产一系列相关的具体的产品
抽象产品:所有产品的基类,提供产品类的公共方法
具体产品:具体的产品类
优点:
1、工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂
2、新加入产品系列时,无需修改原有的系统,增强了系统的可扩展性,符合开闭原则
缺点:
1、在已有产品系列中添加新产品时需要修改抽象层代码,对原有系统改动较大,违背开闭原则。
使用环境:
一系列/一族产品需要被同时使用时,适合使用抽象工厂模式
产品结构稳定,设计完成之后不会向系统中新增或剔除某个产品

类图

结构代码

#ifndef _ABSTRACT_FACTORY_
#define _ABSTRACT_FACTORY_#include<iostream>
#include<string>using namespace std;//抽象产品类AbstractBall
class AbstractBall
{public:AbstractBall() {}virtual ~AbstractBall() {}//抽象方法virtual void play()=0;
};//具体产品类Basketball
class Basketball :public AbstractBall
{public:Basketball(){cout << "get basketball" << endl;}void play(){cout << "play Basketball" << endl;}
};//具体产品类Football
class Football :public AbstractBall
{public:Football(){cout << "get football" << endl;}void play(){cout << "play football" << endl;}
};//抽象产品类AbstractShirt
class AbstractShirt
{public:AbstractShirt() {}virtual ~AbstractShirt() {}//抽象方法virtual void wearshirt() = 0;
};//具体产品类Basketballshirt
class Basketballshirt :public AbstractShirt
{public:Basketballshirt(){cout << "get Basketballshirt" << endl;}//具体实现方法void wearshirt(){cout << "wear basketballshirt" << endl;}
};//具体产品类Footballshirt
class Footballshirt :public AbstractShirt
{public:Footballshirt(){cout << "get Footballshirt" << endl;}//具体实现方法void wearshirt(){cout << "wear footballshirt" << endl;}
};//抽象工厂类
class AbstractFactory
{public:virtual ~AbstractFactory(){}virtual AbstractBall *getBall() = 0;virtual AbstractShirt *getShirt() = 0;
};//具体工厂类BasketballFactory
class BasketballFactory :public AbstractFactory
{public:BasketballFactory(){cout << "get basketballfactory" << endl;}AbstractBall *getBall(){return new Basketball();}AbstractShirt *getShirt(){return new Basketballshirt();}
};//具体工厂类FootballFactory
class FootballFactory :public AbstractFactory
{public:FootballFactory(){cout << "get footballfactory" << endl;}AbstractBall *getBall(){return new Football();}AbstractShirt *getShirt(){return new Footballshirt();}
};#endif

测试代码

#include <iostream>
#include "AbstractFactory.h"
#include <memory>int main()
{// AbstractFactory *fac = NULL;// AbstractBall *ball = NULL;// AbstractShirt *shirt = NULL;// fac = new BasketballFactory();// ball = fac->getBall();// shirt = fac->getShirt();// delete fac;// delete ball;// delete shirt;// fac = new FootballFactory();// ball = fac->getBall();// shirt = fac->getShirt();// delete fac;// delete ball;// delete shirt;//智能指针ashared_ptr<AbstractFactory> fac = make_shared<BasketballFactory>();shared_ptr<AbstractBall> ball = shared_ptr<AbstractBall>(fac->getBall());shared_ptr<AbstractShirt> shirt = shared_ptr<AbstractShirt>(fac->getShirt());fac = make_shared<FootballFactory>();ball = shared_ptr<AbstractBall>(fac->getBall());shirt = shared_ptr<AbstractShirt>(fac->getShirt());system("pause");return 0;
}

4、建造者模式

介绍

功能:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
角色:
抽象建造者:创建一个Product对象的各个部件指定的抽象接口
具体建造者:实现AbstractBuilder的接口,实现各个部件的具体构造方法和装配方法,并返回创建结果
产品:具体的产品对象
指挥者:构建一个使用Builder接口的对象,安排复杂对象的构建过程 (作用:隔离客户与对象的生产过程,并负责控制产品对象的生产过程)
优点:
建造者模式中,客户端不需要知道产品内部组成细节,将产品本身和产品的创建过程分离,使同样的创建过程可以创建不同的产品对象。
不同建造者相互独立,并无任何挂链,方便替换。
缺点
建造者模式所创建的产品一般具有较多的共同点,并组成相似,如果产品之间的差异性很大,则不适用使用建造者模式,因此其使用范围收到一定范围的限制。
如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

适用环境
需要生成的产品对象有复杂的内部结构(通常包含多个成员变量)
产品对象内部属性有一定的生成顺序
同一个创建流程适用于多种不同的产品

类图

结构代码

#ifndef _BUILD_PATTERN_
#define _BUILD_PATTERN_#include<iostream>
#include<string>using namespace std;//产品类House
class House
{public:House() {}void setFloor(string iFloor){this->floor = iFloor;}void setWall(string iWall){this->wall = iWall;}void setRoof(string iRoof){this->roof = iRoof;}//打印House信息void printfHouseInfo(){cout << floor << endl;cout << wall << endl;cout << roof << endl;}private:string floor;string wall;string roof;
};//抽象建造者类AbstractBuilder
class AbstractBuilder
{public:AbstractBuilder(){house = new House();}AbstractBuilder(const AbstractBuilder& o) = delete;AbstractBuilder& operator=(const AbstractBuilder& o) = delete;virtual ~AbstractBuilder(){if (house != nullptr){delete house;house = nullptr;}}//抽象方法virtual void buildFloor() = 0;virtual void buildWall() = 0;virtual void buildRoof() = 0;virtual House *getHouse() = 0;House *house;
};//具体建造者ConcreteBuilderA
class ConcreteBuilderA :public AbstractBuilder
{public:ConcreteBuilderA(){cout << "get ConcreteBuilderA" << endl;}ConcreteBuilderA(const ConcreteBuilderA& o) = delete;ConcreteBuilderA& operator=(const ConcreteBuilderA& o) = delete;~ConcreteBuilderA(){if (this->house != nullptr){delete house;house = nullptr;}}//具体实现方法void buildFloor(){this->house->setFloor("Floor_A");}void buildWall(){this->house->setWall("Wall_A");}void buildRoof(){this->house->setRoof("Roof_A");}House *getHouse(){return this->house;}
};//具体建造者ConcreteBuilderB
class ConcreteBuilderB :public AbstractBuilder
{public:ConcreteBuilderB(){cout << "get ConcreteBuilderB" << endl;}ConcreteBuilderB(const ConcreteBuilderB& o) = delete;ConcreteBuilderB& operator=(const ConcreteBuilderB& o) = delete;~ConcreteBuilderB(){if (this->house != nullptr){delete house;house = nullptr;}}//具体实现方法void buildFloor(){this->house->setFloor("Floor_B");}void buildWall(){this->house->setWall("Wall_B");}void buildRoof(){this->house->setRoof("Roof_B");}House *getHouse(){return this->house;}
};//指挥者Director
class Director
{public:Director() :builder(nullptr) {}~Director(){if (this->builder != nullptr){delete builder;builder = nullptr;}}Director(const Director&) = delete;Director& operator=(Director&) = delete;//具体实现方法void setBuilder(AbstractBuilder *iBuilder){builder = iBuilder;}//封装组装流程,返回建造结果House *construct(){builder->buildFloor();builder->buildWall();builder->buildRoof();return builder->getHouse();}
private:AbstractBuilder *builder;
};#endif

测试代码

#include<iostream>
#include "BuildPattern.h"
using namespace std;int main()
{AbstractBuilder* builder_a = new ConcreteBuilderA();AbstractBuilder* builder_b = new ConcreteBuilderB();shared_ptr<Director> director = make_shared<Director>();director->setBuilder(builder_a);shared_ptr<House> house1 = shared_ptr<House>(director->construct());director->setBuilder(builder_b);shared_ptr<House> house2 = shared_ptr<House>(director->construct());house1->printfHouseInfo();house2->printfHouseInfo();
}

5、原型模式

介绍

功能:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象

角色:
抽象原型类:声明克隆clone自身的接口
具体原型类:实现clone接口
客户端:客户端中声明一个抽象原型类,根据客户需求clone具体原型类对象
优点:
当创建新的对象实例较为复杂时,原型模式可以简化创建过程,提高创建对象的效率
可扩展:模式中提供了抽象原型类,具体原型类可适当扩展
创建结构简单:创建工厂即为原型对象本身
缺点:
深克隆代码较为复杂
每个类都得配备一个clone方法,且该方法位于类的内部,修改时违背开闭原则

适用环境
当创建新的对象实例较为复杂时,原型模式可以简化创建过程
结合优点第三条,需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少几个的组合状态,通过复制原型对象得到新实例,比通过使用构造函数创建一个新实例会更方便。

类图

结构代码

#ifndef PROTOTYPE_PATTERN_
#define PROTOTYPE_PATTERN_#include <iostream>
#include <string>
using namespace std;//work model类
class WorkModel
{public:string modelName;void setWorkModelName(string iName){this->modelName = iName;}
};//抽象原型类PrototypeWork
class PrototypeWork
{public:PrototypeWork() {}virtual ~PrototypeWork() {}virtual PrototypeWork *clone() = 0;
};//具体原型类PrototypeWork
class ConcreteWork :public PrototypeWork
{public:ConcreteWork() {}ConcreteWork(string iName, int iIdNum, string modelName){this->name = iName;this->idNum = iIdNum;this->workModel = new WorkModel();this->workModel->setWorkModelName(modelName);}ConcreteWork *clone(){ConcreteWork *work = new ConcreteWork();work->setName(this->name);work->setIdNum(this->idNum);work->workModel = this->workModel;return work;}~ConcreteWork(){delete workModel;workModel = nullptr;}void setName(string iName){this->name = iName;}void setIdNum(int iIdNum){this->idNum=iIdNum;}void setModel(WorkModel *iWorkModel){this->workModel = iWorkModel;}//打印work信息void printWorkInfo(){cout << this->name << endl;cout << this->idNum << endl;cout << this->workModel->modelName << endl;}private:string name;int idNum;WorkModel *workModel;
};
#endif

测试代码

#include "PrototypePattern.h"int main()
{ConcreteWork *singleWork = new ConcreteWork("Single", 1001, "Single_Model");printf("\nSingle的作业:\n");singleWork->printWorkInfo();ConcreteWork *jungleWork = singleWork->clone();printf("\njungle直接抄作业……\n");jungleWork->printWorkInfo();// 抄完改名字和学号,否则会被老师查出来printf("\njungle抄完改名字和学号,否则会被老师查出来……\n");jungleWork->setName("jungle");jungleWork->setIdNum(1002);WorkModel *jungleModel = new WorkModel();jungleModel->setWorkModelName("Jungle_Model");jungleWork->setModel(jungleModel);// 检查下是否改对了printf("\nSingle的作业:\n");singleWork->printWorkInfo();printf("\nJungle的作业:\n");jungleWork->printWorkInfo();system("pause");delete singleWork;delete jungleModel;delete jungleWork;return 0;
}

6、单例模式

介绍

功能:在项目中会遇到一些工具类,实际上只需要一个对象即可完成所有的工作,因此单例模式为项目仅提供一个对象供使用,节省空间和构造需要的时间
特点:单例模式类的构造函数为私有的,同时需要一个静态该类变量的声明,有懒汉模式和饥饿模式两种,都通过静态方法获取对象实例。懒汉模式,第一次获取该对象时构造该对象实例,之后不再需要重新创建该类型的对象

类图

结构代码

#ifndef _SINGLETON_
#define _SINGLETON_#include<iostream>
#include<string>
#include<mutex>
using namespace std;class Singleton_Lazy
{public:static Singleton_Lazy* getInstance(){cout << "you will get a instance..." << endl;if (instance == nullptr){m_mutex.lock();if (instance == nullptr){cout << "creat a new instance" << endl;instance = new Singleton_Lazy();}else{cout << "you get a old instance" << endl;}m_mutex.unlock();}else{cout << "you get a old instance" << endl;}return instance;}
private:Singleton_Lazy() {}static Singleton_Lazy* instance;static std::mutex m_mutex;
};
Singleton_Lazy* Singleton_Lazy::instance = nullptr;
mutex Singleton_Lazy::m_mutex;class Singleton_Hungry
{public:static Singleton_Hungry* getInstance(){cout << "you will quickly get a instance..." << endl;return instance;}private:Singleton_Hungry() {};static Singleton_Hungry* instance;
};
Singleton_Hungry* Singleton_Hungry::instance = new Singleton_Hungry();#endif 

测试代码

#include "Singleton.h"
int main()
{Singleton_Lazy* lazy1 = Singleton_Lazy::getInstance();Singleton_Lazy* lazy2 = Singleton_Lazy::getInstance();Singleton_Hungry* hungry = Singleton_Hungry::getInstance();return 0;
}

7、代理模式

介绍

功能:由于某些原因需要给某个对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
角色:
抽象角色:一般会使用接口或抽象类来解决
真实角色:被代理的角色
代理角色:代理真实的角色,代理真实角色后我们会进行一些附属操作
访问角色:访问代理对象的人(测试时的main函数)
优点:可以使真实角色的操作更加纯粹!不用关注一些公共的业务,公共也就可以交给代理角色,实现了业务的分工,公共业务发生扩展的时候,方便管理
代理模式的缺点:一个真实的角色就会产生一个代理角色,代码量会翻倍开发效率会变低,也许,这样无法理解到代理模式的好处。或者说:我们想要在原有固定的功能上新增业务,按照开闭原则我们是不能对原有代码进行修改的。但是我们可以通过代理模式,增加代理,在实现原有功能的情况下写入新的功能,创建对象时也就可以使用代理,完成操作。

类图

结构代码

#ifndef _PROXYPATTERN_
#define _PROXYPATTERN_
#define _CRT_SECURE_NO_WARNINGS 1
#include<mutex>
#include<iostream>
#include<string>using namespace std;//抽象主题色
class Subject
{public:Subject() {}virtual ~Subject() {}virtual void method() = 0;
};//真实主题颜色
class RealSubject :public Subject
{public:RealSubject() {}virtual ~RealSubject() {}void method(){cout << "调用业务方法" << endl;}
};//Log类
class Log
{public:Log() {};string getTime() {time_t t = time(NULL);char ch[64] = { 0 };//年-月-日 时-分-秒strftime(ch, sizeof(ch) - 1, "%Y-%m-%d %H:%M:%S", localtime(&t));return ch;}
};//代理类
class Proxy:public Subject
{public:Proxy(){realsubject = new RealSubject();log = new Log();}Proxy(const Proxy& o) = delete;Proxy& operator=(const Proxy& o) = delete;~Proxy(){delete realsubject;delete log;realsubject = nullptr;log = nullptr;}void preCallMethod(){cout << "方法method()被调用,调用时间为"<<log->getTime() << endl;}void method(){preCallMethod();realsubject->method();postCallMethod();}void postCallMethod(){cout << "方法method()调用成功" << endl;}
private:RealSubject *realsubject;Log* log;
};#endif //

测试代码

#include "ProxyPattern.h"int main()
{Proxy p;p.method();return 0;
}

8、装饰者模式

介绍

功能:动态地将新功能附加到对象上。在对象功能的拓展方面,比继承更有弹性。同时装饰者也体现了开闭原则
角色:
抽象构件(component):定义一个抽象接口以规范准备接收附加责任的对象
具体构件(concreteComponent):实现抽象构件,通过装饰角色为其添加一些职责(或者说功能)
抽象装饰(Decorator):继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体的构件功能
具体装饰(ConcreteDecorator):实现抽象类装饰的相关方法,并给具体构建对象添加附加的责任

类图

结构代码

#ifndef _DECORATOR_
#define _DECORATOR_#include <iostream>
using namespace std;//抽象构件
class Component
{public:Component() {}virtual ~Component() {}virtual void operation() = 0;
};//具体构件
class Phone:public Component
{public:Phone() {}void operation(){cout << "手机" << endl;}
};//
class Pad :public Component
{public:Pad() {}void operation(){cout << "平板" << endl;}
};//抽象装饰类
class Decorator :public Component
{public:Decorator() {}Decorator(Component *c){this->component = c;}void operation(){this->component->operation();}Component *getComponent(){return component;}void setComponent(Component *c){this->component = c;}
private:Component *component;
};//具体装饰类:外壳
class DecoratorShell :public Decorator
{public:DecoratorShell(){}DecoratorShell(Component* c){this->setComponent(c);}void operation(){this->getComponent()->operation();this->newBehavior();}void newBehavior(){cout << "安装外壳" << endl;}
};
//具体装饰类:挂绳
class DecoratorRope :public Decorator
{public:DecoratorRope() {}DecoratorRope(Component* c){this->setComponent(c);}void operation(){this->getComponent()->operation();this->newBehavior();}void newBehavior(){cout << "安装挂绳" << endl;}
};// 具体装饰类:贴纸
class DecoratorSticker :public Decorator
{public:DecoratorSticker() {}DecoratorSticker(Component *c) {this->setComponent(c);}void operation() {this->getComponent()->operation();this->newBehavior();}void newBehavior() {cout << "安装卡通贴纸" << endl;}
};#endif // !_DECORATOR_

测试代码

#include "DecoratorPattern.h"int main()
{Component *phone = new Phone();Component *pad = new Pad();Component *shell = new DecoratorShell(phone);Component *rope = new DecoratorRope(phone);Component *sticker = new DecoratorSticker(phone);shell->operation();rope->operation();sticker->operation();Component *shell2 = new DecoratorShell(pad);Component *rope2 = new DecoratorRope(pad);Component *sticker2 = new DecoratorSticker(pad);shell2->operation();rope2->operation();sticker2->operation();return 0;
}

设计模式--C++学习(4)相关推荐

  1. 基于设计模式的学习之旅-----访问者模式(附源码)

    基于设计模式的学习之旅-----访问者模式 1.初始访问者模式 2.什么是访问者模式 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 3.模 ...

  2. C#设计模式(学习笔记[01])

    C#设计模式(学习笔记[01])<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office&quo ...

  3. 《游戏设计模式》学习笔记

    ** <游戏设计模式>学习笔记 ** 原作中文版传送门:<游戏设计模式> 原书作者:Bob Nystrom 阅读背景:最近担任了主程(惭愧,整个项目组就我一个人,2333),在 ...

  4. 设计模式总结篇(为什么要学习设计模式,学习设计模式的好处)

    版权声明:转载必须注明本文转自晓_晨的博客:http://blog.csdn.net/niunai112 在学习完设计模式后,LZ想告诉大家: 对于一名工作不久的程序员来说,学习设计模式是非常有必要的 ...

  5. 软件设计模式的学习(以Java为例)

    软件设计模式的学习(以Java为例) 单例模型 定义: 懒汉模式 饿汉模式 单例模式的优缺点 优点 缺点 工厂模式 定义 分类 工厂方法模式 抽象工厂模式 代码实现 优点 缺点 文章引用 软件设计模式 ...

  6. 23种设计模式的学习

    23种设计模式的学习 什么是设计模式 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解. ...

  7. 打印鸭子戏水java,《Head first设计模式》学习笔记 #8211; 策略模式,

    <Head first设计模式>学习笔记 – 策略模式, 策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 假设有一个模拟鸭子的游戏,游 ...

  8. 秘籍:设计模式PDF学习笔记!

    周五晚上抽时间逛GitHub基本是常规例行操作,昨晚无意中看到一位GitHub大佬(https://github.com/fuzhengwei)的设计模式学习笔记,一时间语塞,瞬间嘴角微微上扬!有些小 ...

  9. 大佬的设计模式PDF学习笔记!

    周五晚上抽时间逛GitHub基本是常规例行操作,昨晚无意中看到一位GitHub大佬(https://github.com/fuzhengwei)的设计模式学习笔记,一时间语塞,瞬间嘴角微微上扬!有些小 ...

  10. Java设计模式(学习整理)---命令模式

    设计模式之Command(学习整理) 1.Command定义 不少Command模式的代码都是针对图形界面的,它实际就是菜单命令,我们在一个下拉菜单选择一个命令时,然后会执行一些动作. 将这些命令封装 ...

最新文章

  1. python3 ipaddress模块 创建 检查 操作ip地址 简介
  2. python编写程序-Python 编程速成(推荐)
  3. 求生之路显示服务器指令,求生之路2控制台指令..doc
  4. CCF NOI1000 加密算法
  5. 【NOIP2000】【Luogu1019】单词接龙
  6. [转载] Python字符串操作方法详解
  7. (转)SQL Server 监控统计阻塞脚本信息
  8. pythondjango搭建数据管理平台_python+django 搭建整个平台流程
  9. C++轻量级微服务_微服务的部署
  10. 号外:中国雅虎相册即将关闭原图下载 请网友及时备份
  11. 塞班系统是如何没落的
  12. emule服务器无响应是什么原因,为什么,一直无响应,求大神帮忙
  13. 古诗词网站源码 php,帝国cms 诗词整站源码
  14. 微信小程序毕业设计 基于微信校园二手交易信息小程序系统开题报告
  15. maven失败测试用例rerun插件使用方法
  16. Swift 编程语言教程(官方文档)
  17. C++实现ID3决策树(UCI DNA数据集)
  18. [安装fastfds中的nginx执行make命令报错]src/core/ngx_murmurhash.c:37:11: error
  19. 【ELT.ZIP】OpenHarmony啃论文俱乐部——多维探秘通用无损压缩
  20. java ajax serialize,jQuery使用serialize(),serializeArray()方法取得表单数据

热门文章

  1. CUDA核函数share memory
  2. 《那些年啊,那些事——一个程序员的奋斗史》三
  3. 【进销存管理系统——开题报告 分享(仅供参考呀)】
  4. Javascript时间脚本收集
  5. undo歌词中文音译_T-ara - Lovey Dovey 罗马拼音+中文歌词+韩文歌词+中文音译
  6. android 歌词同步 换行,AS3歌词同步详解
  7. IXDC2018国际体验设计大会精华汇总,微软、阿里巴巴、小米、Adobe等大咖都说了啥?...
  8. 最新PHP超精简全站自适应小说网网站源码
  9. MZD Studios|感谢你们,我挺过来了,不做老外舔狗 -Jerome Alan Chan
  10. 控制工程实践(11)——控制系统辨识