设计模式----持续学习更新中
学习总结,文章内容学自:添加链接描述
类图介绍
类图由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;
//智能指针a
shared_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;
}
记录
代理模式(ProxyPattern)和装饰者模式(DecoratorPattern)很像,都是将一个对象传入一个类的构造函数中,这样生成的新对象就具有使用传入对象中一些约定好的函数功能
可以在此基础上添加一些复杂逻辑