创建型设计模式
用来创建对象
单例模式
特点:一个类只能有一个实例
优点:减少内存开销,避免资源的多重占用,优化共享资源的访问
缺点:扩展困难,违背开闭原则,用以违背单一职责原则
实现
#include<iostream>
/**
* @brief 懒汉模式:
* 特点:简单,但是会导致进程启动慢(main函数执行前完成初始化),启动顺序不确定
*/
class LazySingleton{
private:
LazySingleton(){}//私有的,不能被实例化
static LazySingleton instance;//使用实例,main函数执行前完成初始化
};
LazySingleton LazySingleton::instance;
#include<mutex>
#include<thread>
/**
* @brief 饿汉模式
* 跟懒汉模式的特点相反
*
* 获取实例使用了 线程互斥
*/
class HungrySingleton{
private:
HungrySingleton(){}//私有的,不能被实例化
static HungrySingleton *instance;//使用指针,进程无负载
};
HungrySingleton *HungrySingleton::instance = nullptr;
原型模式
特点:有浅拷贝和深拷贝两种
优点:比直接new一个对象更加优良,简化创建对象的过程
缺点:需要为每一个类配置一个clone方法,违背开闭原则
实现
class Protype{
public:
virtual Protype* clone()=0;//通过克隆自己来创建
};
class ConcreteProtypeA:public Protype
{
public:
Protype* clone(){
return new ConcreteProtypeA(*this);
}
};
class MainFrom{
Protype* prototype;//原型对象
public:
MainFrom(Protype* p)
{
this->prototype = p;
}
void Button1_Click(){
Protype *p = prototype->clone();//克隆原型
}
};
#include<iostream>
/**
* @brief 克隆
*/
class Clone{
public:
void show() const{
std::cout << "name: "<< name->c_str()<<" address: "<<name<<std::endl;
}
Clone():name(nullptr){}
Clone(const char* nm){
this->name = new std::string(nm);
}
//clone,深拷贝
Clone(const Clone& obj)
{
if(name)
name->assign(obj.name->c_str());
else
name = new std::string(obj.name->c_str());
}
//赋值拷贝,浅拷贝
Clone& operator = (const Clone& obj)
{
if(name)
name->assign(obj.name->c_str());
else
name = new std::string(obj.name->c_str());
return *this;
}
private:
std::string *name;
};
工厂模式
简单工厂
/**
* @brief 简单工厂模式:创建和使用分离
* 缺点:违背了开闭原则
*/
class Product{
public:
virtual void show()=0;
};
class ConcreteProductA : public Product
{
public:
void show(){
}
};
class Factory//违背了开闭原则,增/减一个产品要修改内部代码
{
public:
Product *makeProductA(){
return new ConcreteProductA();
}
};
工厂方法
/**
* @brief 工厂方法:满足开闭原则的简单工厂模式
* 缺点:抽象产品只能生成一种产品
* 实现:抽象工厂,具体工厂,抽象超,具体产品
*
*/
class AbstractProduct
{
public:
virtual void show()=0;
};
class ConcreteProductA : public AbstractProduct
{
public:
void show(){
}
};
class AbstractFactory
{
public:
virtual AbstractProduct* makeProduct()=0;
};
//增加一个产品需要新增一个工厂
class ConcreteFactoryA : public AbstractFactory
{
public:
AbstractProduct* makeProduct(){
return new ConcreteProductA();
}
};
抽象工厂
/**
* @brief 抽象工厂:为访问类提供相互依赖对象的接口
* 缺点:新增新产品时,工厂类需要修改(违反开闭原则)
* 实现:抽象工厂,具体工厂,抽象产品,具体产品
*/
class AbstractProduct
{
public:
virtual void show()=0;
};
class ConcreteProductA : public AbstractProduct
{
public:
void show(){
}
};
class AbstractFactory
{
public:
virtual AbstractProduct* makeProduct()=0;
};
//新增一个产品时,需要修改工厂类,违反开闭原则
class ConcreteFactory : public AbstractFactory
{
public:
AbstractProduct* makeProductA(){
return new ConcreteProductA();
}
};
建造者模式
特点:通常与工厂方法模式结合使用
优点:封装性良好,构建和表示分离,扩展性好,可以对创建过程逐步细化
缺点:产品的组成部分必须相同
实现
class Product
{
public:
void showA(){
}
};
class AbstractBuilder
{
public:
virtual void makeProduct()=0;
Product get(){
return product;
}
protected:
Product product;
};
class ConcreteBuilder:public AbstractBuilder
{
public:
void makeProduct(){
product.showA();
}
};
//指挥者负责获取产品,调用工厂生产产品
class Director
{
public:
Product get(){
return _builder->get();
}
void set(AbstractBuilder *builder)
{
_builder = builder;
}
void construct(){
_builder->makeProduct();
}
private:
AbstractBuilder *_builder;
};