常见的创建型设计模式( 一 )

设计模式( 一 )

常见的创建型设计模式

1.单例模式 : 确保一个类只有一个实例 , 为整个程序提供一个全局的访问接口。getInstance

实现方式

  • 饿汉式 ,在调用getInstance 创建实例的时候 ,实例已经存在了 ,不需要我们再次去 new 创建。
    优点: 实现简单 , 在多线程的环境下是线程安全的。
cpp 复制代码
class Singleton {
  public:
  	static Singleton* getInstance() {
  		return singleton.get();   // 返回管理的原始指针
  	}
  	~Singleton() { cout << __FUNCTION__ << endl;  }
  private:
  	Singleton() { cout << __FUNCTION__ << endl; }
  	
  
  	Singleton(const Singleton& other) = delete;
  	Singleton& operator =(const Singleton& other) = delete;
  
  	static unique_ptr< Singleton >singleton;  // 用智能指针来托管这个有生命周期的对象.避免我们手动去释放
  };
  
  unique_ptr< Singleton>Singleton::singleton( new Singleton);
  • 懒汉式 ,第一次使用的时候, 才初始化实例
    缺点: 不适合多线程环境( 如果要在多线程下使用 ,需要加锁 )
    优点: 节省资源
cpp 复制代码
  // 利用C++11的新特性 线程安全且简单
  #include <mutex>
  
  class Singleton {
  public:
  	static Singleton* getInstance() {
  		call_once(flag, []() {   // 保存对象只 new 一次
  			singleton.reset(new Singleton);
  			});
  		return singleton.get(); // 返回管理的原始指针
  	}
  	
  	~Singleton() { cout << __FUNCTION__ << endl; }
  private:
  	Singleton() { cout << __FUNCTION__ << endl; }
  	
  	Singleton(const Singleton& other) = delete;
  	Singleton& operator =(const Singleton& other) = delete;
  
  	static unique_ptr<Singleton>singleton;
  	static once_flag flag;
  };
  
  unique_ptr< Singleton>Singleton::singleton;
  once_flag Singleton::flag;
  
  
  // 其他的写法 ,可以参考
  class Singleton {
  public:
  	static Singleton* getInstance() {
  		statict Singleton singleton;
          return &singleton;
  	}
  private:
  	Singleton() { cout << __FUNCTION__ << endl; }
      ~Singleton() { cout << __FUNCTION__ << endl; }
  	
  	Singleton(const Singleton& other) = delete;
  	Singleton& operator =(const Singleton& other) = delete;
  };
 

适用场景 : 线程池 、系统日志、内存池。等等

2.简单工厂模式 : 定义一个工厂类 , 用来创建不同类型的对象实例 .

目的: 将对象创建的过程封装在工厂类里面 , 我们只需要调用工厂类的生产 方法 ,而不需要关心具体的实现过程.

基本结构

  • 工厂类 --->用于创建对象的实例
  • 产品类 ---> 创建对象的父类
  • 具体产品类----> 继承产品类 , 重写父类的virtual 方法.

具体实现方法:

cpp 复制代码
// 产品类
class Animal {
public:
	Animal() { }; 
	virtual void eat() = 0;
	virtual void drinking() = 0;

	virtual ~Animal( ) { }
};

// 具体产品类
class Dog :public Animal {
public:
	Dog() { }
	virtual ~Dog() { }

	virtual void eat() { std::cout << "++ Dog eat" << std::endl; }
	virtual void drinking() { std::cout << "++ Dog drinking" << std::endl; }
};

// 具体产品类
class Cat :public Animal {
public:
	Cat() { }
	virtual ~Cat() { }

	virtual void eat() { std::cout << "++ Cat eat" << std::endl; }
	virtual void drinking() { std::cout << "++ Cat drinking" << std::endl; }
};

// 具体产品类
class Beef :public Animal {
public:
	Beef() { }
	virtual ~Beef() { }

	virtual void eat() { std::cout << "++ Beef eat" << std::endl;  }
	virtual void drinking() { std::cout << "++ Beef drinking" << std::endl;  }
};

// 产品类型
enum class AnimalType :char
{
	Dog,
	Cat,
	Beef
};

// 工厂类
class Factory {
public:
	Factory() { };
	~Factory() { };
	// 生产
	Animal* make_animal( AnimalType  type ) {
		Animal* animal = nullptr;
		switch ( type )
		{
		case AnimalType::Cat:
			animal = new Cat;
			break;
		case AnimalType::Dog:
			animal = new Dog;
			break;
		case AnimalType::Beef:
			animal = new Beef;
			break;
		default:
			break;
		}
		return animal;
	}
};


int main( ) {
	
    // 创建一个工厂实例 , 调用生产方法 ,生成我们需要的产品.
	Factory factory;   

	Animal* Beef = factory.make_animal(AnimalType::Beef);
	Beef->drinking();

	Animal* Dog = factory.make_animal(AnimalType::Dog);

	Dog->eat();

	system("pause");

	return 0;
}

适用场景: 创建对象的逻辑较为简单、对象类型较少。

3.工厂模式: 它定义了一个创建对象的工厂,但由工厂的子类决定生成哪一个产品。

基本结构:

  • 工厂类 --->定义生产产品的接口
  • 具体工厂类--->继承工厂类 , 对生产接口进行具体实现。返回具体的产品实例
  • 产品类--->定义产品的父类
  • 具体产品类 ---> 继承产品类 ,实现产品类的具体方法。

具体的实现:

cpp 复制代码
// 产品类
class Animal {
public:
	Animal() { }; 
	virtual void eat() = 0;
	virtual void drinking() = 0;

	virtual ~Animal( ) { }
};

// 具体产品类
class Dog :public Animal {
public:
	Dog() { }
	virtual ~Dog() { }

	virtual void eat() { std::cout << "++ Dog eat" << std::endl; }
	virtual void drinking() { std::cout << "++ Dog drinking" << std::endl; }
};

// 具体产品类
class Cat :public Animal {
public:
	Cat() { }
	virtual ~Cat() { }

	virtual void eat() { std::cout << "++ Cat eat" << std::endl; }
	virtual void drinking() { std::cout << "++ Cat drinking" << std::endl; }
};

// 具体产品类
class Beef :public Animal {
public:
	Beef() { }
	virtual ~Beef() { }

	virtual void eat() { std::cout << "++ Beef eat" << std::endl;  }
	virtual void drinking() { std::cout << "++ Beef drinking" << std::endl;  }
};

// 工厂类
class AbstractFactory {
public:
	AbstractFactory() { };
	virtual ~AbstractFactory() { };
	// 生产
	virtual Animal* make_animal( ) = 0;
};

// 具体工厂类
class DogFactory : public AbstractFactory {
public:
	DogFactory() { }
	virtual ~DogFactory() { }

	virtual Animal* make_animal() {
		return new Dog;
	}
};

// 具体工厂类
class CatFactory : public AbstractFactory {
public:
	CatFactory() { }
	virtual ~CatFactory() { }

	virtual Animal* make_animal() {
		return new Cat;
	}
};

// 具体工厂类
class BeefFactory : public AbstractFactory {
public:
	BeefFactory() { }
	virtual ~BeefFactory() { }

	virtual Animal* make_animal() {
		return new Beef;
	}
};

int main( ) {
	
	// 创建一个狗的工厂 ,用于生产狗
	AbstractFactory  *factory_dog = new DogFactory;
	Animal* dog = factory_dog->make_animal();

	dog->eat();

	// 创建一个猫的工厂 ,用于生产猫
	AbstractFactory* factory_cat = new CatFactory;
	Animal* cat = factory_cat->make_animal();

	cat->drinking();

	system("pause");

	return 0;
}

工厂模式是对简单工厂模式的优化 , 将生产产品的的过程延申到工厂的子类中进行实现 , 提高程序的可扩展性。

4.抽象工厂模式: 提供一系列创建产品的接口 , 无需指定具体的类.

适用于: 生产的产品结构比较复杂的类, 入电脑 , 汽车( 由很多零部件构成 , 而同一个零部件又有很多类型).

基本结构:

  • 抽象工厂---> 定义创建产品的方法.
  • 具体工厂---> 实现创建产品的方法 , 这些方法会返回一个具体的产品.
  • 抽象产品 ---> 为每种产品声明一个接口.
  • 具体产品 ---> 实现抽象产品的接口.
  • 客户端 ---> 通过抽象工厂和抽象产品来生产产品.

例如: 建造一海贼艘船

|---------------------- --基础版-----------------豪华版----------------旗舰版 |

| 动力系统------------船桨--------------------内燃机----------------核动力 |

| 防御系统------------防空机枪--------------反舰导弹-------------激光炮 |

| 创建材料------------木头--------------------钢铁-------------------合金 |

具体实现:

cpp 复制代码
#include <iostream>
#include <string>

// 动力系统抽象类
class AbstractPower {
public:
	AbstractPower() {  }
	virtual ~AbstractPower( ) { }

	virtual std::string getPower() = 0;
};

// 船桨动力
class BodyPower : public AbstractPower {
public:
	BodyPower() { }
	virtual ~BodyPower() { }

	virtual std::string getPower() {
		return std::string("< 船桨>动力系统");
	}
};

// 内燃机
class EnginePower : public AbstractPower {
public:
	EnginePower() { }
	virtual ~EnginePower() { }

	virtual std::string getPower() {
		return std::string("< 内燃机>动力系统");
	}
};

// 核动力
class EnergyPower : public AbstractPower {
public:
	EnergyPower() { }
	virtual ~EnergyPower() { }

	virtual std::string getPower() {
		return std::string("< 核能>动力系统");
	}
};

// 防御系统抽象类
class AbstractDefense {
public:
	AbstractDefense() { }
	virtual ~AbstractDefense() { }

	virtual std::string getDefense() = 0;
};

// 防空机枪
class Gun : public AbstractDefense {
public:
	Gun() { }
	virtual ~Gun() { }

	virtual std::string getDefense() {
		return std::string("<防空机枪>防御系统");
	}
};

// 反舰导弹
class Guided : public AbstractDefense {
public:
	Guided() { }
	virtual ~Guided() { }

	virtual std::string getDefense() {
		return std::string("<防空导弹>防御系统");
	}
};

// 激光炮
class Laser : public AbstractDefense {
public:
	Laser() { }
	virtual ~Laser() { }

	virtual std::string getDefense() {
		return std::string("<激光炮>防御系统");
	}
};

// 建造材料抽象类
class AbstractMaterials {
public:
	AbstractMaterials() { }
	virtual ~AbstractMaterials() { }

	virtual std::string getMaterials() = 0;
};

// 木头
class Wood :public AbstractMaterials {
public:
	Wood() { }
	virtual ~Wood() { }

	virtual std::string getMaterials() {
		return std::string("<木头>建造");
	}
};

// 钢铁
class Steel :public AbstractMaterials {
public:
	Steel() { }
	virtual ~Steel() { }

	virtual std::string getMaterials() {
		return std::string("<钢铁>建造");
	}
};

// 合金
class Alloy :public AbstractMaterials {
public:
	Alloy() { }
	virtual ~Alloy() { }

	virtual std::string getMaterials() {
		return std::string("<合金>建造");
	}
};

// 船
class Shop {
public:
	Shop(AbstractPower* power, AbstractDefense* defence, AbstractMaterials* materials):power_(power), defence_(defence), materials_( materials ){  }

	~Shop( ) { 
		delete power_;
		delete defence_;
		delete materials_;
	}
	std::string getShopInforamtion() {
		std::string info = power_->getPower() + defence_->getDefense() + materials_->getMaterials();
		return info;
	}
private:
	AbstractPower* power_;         // 动力系统
	AbstractDefense* defence_;     // 防御系统
	AbstractMaterials* materials_;  // 建造材料
};


// 工厂抽象类
class AbstractFactory {
public:
	AbstractFactory( ) { }
	virtual ~AbstractFactory() { }

	virtual Shop* CreateShop() = 0;
};

class BasicShop :public AbstractFactory {
public:
	BasicShop( ) { }
	virtual ~BasicShop( ){ }

	virtual Shop* CreateShop() {
		Shop* shop = new Shop(new BodyPower, new Gun, new Wood);
		std::cout << "<基础形>海贼船建造完毕" << std::endl;
		return shop;
	}
};

// 
class LuxuryShop :public AbstractFactory {
public:
	LuxuryShop() { }
	virtual ~LuxuryShop() { }

	virtual Shop* CreateShop() {
		Shop* shop = new Shop(new EnginePower, new Guided, new Steel);
		std::cout << "<豪华型>海贼船建造完毕" << std::endl;
		return shop;
	}
};

class FlagshipShop :public AbstractFactory {
public:
	FlagshipShop() { }
	virtual ~FlagshipShop() { }

	virtual Shop* CreateShop() {
		Shop* shop = new Shop( new EnergyPower , new Laser, new Alloy);
		std::cout << "<旗舰型>海贼船建造完毕" << std::endl;
		return shop;
	}
};

int main() {
	
	AbstractFactory* factory = new BasicShop;
	Shop *shop = factory->CreateShop();
	std::cout << shop->getShopInforamtion() << std::endl;

	return 0;
}

效果演示:

相关推荐
bananawolf13 分钟前
C++部分复习笔记上
c++·笔记
ztenv21 分钟前
C++23特性一览
linux·c++·c++23
xy1899027 分钟前
C++线程安全是如何保证的?线程不安全是如何出现的?有什么处理方案呢
开发语言·c++·安全
ztenv27 分钟前
编译器对C++23的支持程度
c++·c++23
这题怎么做?!?1 小时前
自我反思与暑假及大三上学期规划
linux·数据结构·c++
WHAT8161 小时前
【CUDA】 由GPGPU控制核心架构考虑CUDA编程中线程块的分配
开发语言·c++·人工智能·架构
大卫的纯爱战士4 小时前
c++指针和引用之高难度(二)习题讲解
开发语言·c++
潜水大王5 小时前
C++轻量级 线程间异步消息架构(向曾经工作的ROSA-RB以及共事的DOPRA的老兄弟们致敬)
c++·架构
画饼校长5 小时前
【C++ Primer Plus学习记录】函数的基本知识
开发语言·c++·学习·visualstudio·软件工程
情系明明5 小时前
使用c++设计一个计算器
数据结构·c++·算法