一、设计模式思想
设计模式本质是开发人员经验的总结,目的是为提升软件的高内聚、低耦合特性。它无法像算法解决具体的实际问题,只是一种优化代码的推荐方式。
根据设计模式的参考书,目前有23种设计模式,分为创建型、结构型和行为型。以下介绍最常用的2种设计模式:单例模式和工厂模式。
二、单例模式
单例模式(Singleton Pattern)是最简单的设计模式之一。它属于创建型模式,提供了一种创建对象的最佳方式。
当想控制实例数目,并节省系统资源时,推荐使用单例模式。这种模式确保了一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式要求:
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给所有其他对象提供这一实例
单例模式主要分为懒汉模式和饿汉模式。
1.懒汉模式(线程非安全)
懒汉模式,即指在第一次用到类实例时,才去实例化一个对象,减少内存浪费,以时间换空间,适合访问量较小的情况。但不加锁时,会存在线程不安全。
class Singleton
{
public:
static Singleton* GetInstance();
~Singleton(){}
private:
Singleton(){}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton *instance;
};
Singleton* Singleton::instance = NULL;
Singleton* Singleton::GetInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
};
2.懒汉模式(线程安全)
采用双重校验锁,保证了多线程下的安全且高性能。
std::mutex mtx;
class Singleton
{
public:
static Singleton* GetInstance();
~Singleton(){}
private:
Singleton(){}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton *instance;
};
Singleton* Singleton::instance = nullptr;
Singleton* Singleton::GetInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lk(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
3.饿汉模式
饿汉模式,即指在类加载时就初始化,存在内存浪费,但是不加锁的方式,提升了效率,以空间换时间。这种模式保证了线程安全。
class Singleton
{
public:
static Singleton* GetInstance();
~Singleton(){}
private:
Singleton(){}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* instance;
};
Singleton* Singleton::instance = new Singleton();
Singleton* Singleton::GetInstance() {
return instance;
}
三、工厂模式
工厂模式(Factory Pattern)是最常用的设计模式之一,属于创建型模式。它定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,使其创建过程延迟到子类进行。
这种模式便于扩展,屏蔽了产品的具体实现,适合生成复杂对象的场合。
1.简单工厂
简单工厂实现的是,让其子类实现工厂接口,返回的是一个抽象的产品。
class Shape
{
public:
virtual void draw() = 0;
};
class Rectangle: public Shape
{
public:
void draw() override {
cout << "Rectangle" << endl;
}
};
class Circle: public Shape
{
public:
void draw() override {
cout << "Circle" << endl;
}
};
class Square : public Shape
{
public:
void draw() override {
cout << "Square " << endl;
}
};
class ShapeFactory
{
public:
Shape* GetShape(string shapeType) {
if(shapeType == "Circle"){
return new Circle();
}
else if(shapeType == "Rectangle"){
return new Rectangle();
}
else if(shapeType == "Square"){
return new Square();
}
return nullptr;
}
};
int main()
{
ShapeFactory *shapeFactory = new ShapeFactory();
Shape* shape1 = shapeFactory->GetShape("Circle");
shape1->draw();
Shape* shape2 = shapeFactory->GetShape("Rectangle");
shape2->draw();
Shape* shape3 = shapeFactory->GetShape("Square");
shape3->draw();
return 0;
}
2.抽象工厂
抽象工厂是围绕一个超级工厂创建其他工厂,适用于系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
class Shape
{
public:
virtual void draw() = 0;
};
class Rectangle: public Shape
{
public:
void draw() override {
cout << "Rectangle" << endl;
}
};
class Circle: public Shape
{
public:
void draw() override {
cout << "Circle" << endl;
}
};
class Square : public Shape
{
public:
void draw() override {
cout << "Square " << endl;
}
};
class Color
{
public:
virtual void draw() = 0;
};
class Red: public Color
{
public:
void draw() override {
cout << "Red" << endl;
}
};
class Green: public Color
{
public:
void draw() override {
cout << "Green" << endl;
}
};
class Blue : public Color
{
public:
void draw() override {
cout << "Blue " << endl;
}
};
class AbstractFactory
{
public:
virtual Color* GetColor(string colorType){}
virtual Shape* GetShape(string shapeType){}
};
class ShapeFactory : public AbstractFactory
{
public:
Shape* GetShape(string shapeType) override {
if(shapeType == "Circle"){
return new Circle();
}
else if(shapeType == "Rectangle"){
return new Rectangle();
}
else if(shapeType == "Square"){
return new Square();
}
return nullptr;
}
};
class ColorFactory : public AbstractFactory
{
public:
Color* GetColor(string colorType) override {
if(colorType == "Red"){
return new Red();
}
else if(colorType == "Green"){
return new Green();
}
else if(colorType == "Blue"){
return new Blue();
}
return nullptr;
}
};
class FactoryProducer
{
public:
static AbstractFactory* getFactory(string choice) {
if(choice == "Shape") {
return new ShapeFactory();
}
else if(choice == "Color") {
return new ColorFactory();
}
return nullptr;
}
};
int main()
{
AbstractFactory* shapeFactory = FactoryProducer::getFactory("Shape");
Shape* shape1 = shapeFactory->GetShape("Circle");
shape1->draw();
Shape* shape2 = shapeFactory->GetShape("Rectangle");
shape2->draw();
Shape* shape3 = shapeFactory->GetShape("Square");
shape3->draw();
AbstractFactory* colorFactory = FactoryProducer::getFactory("Color");
Color* color1 = colorFactory->GetColor("Red");
color1->draw();
Color* color2 = colorFactory->GetColor("Green");
color2->draw();
Color* color3 = colorFactory->GetColor("Blue");
color3->draw();
return 0;
}