创建型模式包括工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式;
结构型模式包括适配器模式、桥接模式、过滤器模式、组合模式、装饰器模式、外观模式、享元模式、代理模式;
行为型模式包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、空对象模式、策略模式、模板模式、访问者模式。

工厂模式是最常用的设计模式之一,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂方法由一个抽象产品类和一个抽象工厂组成,它让子类自己决定实例化哪一个工厂类,每一个工厂类对应了一个产品类。
优点: 1、调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
C++示例:
我们有Rectangle和Circle两个具体的产品类,他们可以抽象出一个抽象产品类Shape。同时有FactoryRectangle和FactoryCircle两个具体工厂类,他们继承自抽象工厂类Factory。每一个具体工厂类与一个具体产品类相对应。
// 形状接口,抽象产品类class Shape{public: virtual void draw() = 0;};// 具体产品1class Rectangle : public Shape {public: Rectangle(){} void draw() { cout<<"矩形类"<<endl; }};// 具体产品2class Circle : public Shape {public: Circle(){} void draw() { cout<<"圆形类"<<endl; }};// 抽象工厂类class Factory {public: virtual Shape creatShape() = 0;};// 具体工厂1class FactoryRectangle : public Factory {public: Shape creatShape() { return new Rectangle(); }};// 具体工厂2class FactoryCircle : public Factory {public: Shape creatShape() { return new Circle(); }};// 客户int main() { Factory factory1 = new FactoryRectangle(); Factory factory2 = new FactoryCircle(); Shape rectangle = factory1->creatShape(); Shape circle = factory2->creatShape(); rectangle->draw(); circle->draw(); return 0;}/ 输出矩形类圆形类/
抽象工厂模式 (Abstract Factory Pattern)
抽象工厂模式是围绕一个超级工厂来创建其他工厂。在工厂模式中,一个工厂对应着一种产品,而抽象工厂中,一个工厂对应着一类产品,即提供一个创建一系列相关或相互依赖对象的接口。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
C++示例:
有单核和多核两种处理器,即抽象产品类SingleCore和MultiCore,每种类型处理器又分为A和B两种型号,因此一共有SingleCoreA,SingleCoreB,MultiCoreA和MultiCoreB四种具体产品类,其中工厂A即FactoryA类负责A型号的生产,工厂B即FactoryB负责B型号的生产。
// 抽象产品类-单核 class SingleCore { public: virtual void Show() = 0;}; // 具体产品类-单核class SingleCoreA: public SingleCore { public: SingleCoreA(){ this->Show(); } void Show() { cout<<"单核A"<<endl; } }; class SingleCoreB :public SingleCore { public: SingleCoreB(){ this->Show(); } void Show() { cout<<"单核B"<<endl; } }; // 抽象产品类-多核 class MultiCore { public: virtual void Show() = 0;}; // 具体产品类-多核class MultiCoreA : public MultiCore { public: MultiCoreA(){ this->Show(); } void Show() { cout<<"多核A"<<endl; } }; class MultiCoreB : public MultiCore { public: MultiCoreB(){ this->Show(); } void Show() { cout<<"多核B"<<endl; } }; // 抽象工厂类 class CoreFactory { public: virtual SingleCore CreateSingleCore() = 0; virtual MultiCore CreateMultiCore() = 0;}; // 工厂A class FactoryA :public CoreFactory { public: SingleCore CreateSingleCore() { return new SingleCoreA(); } MultiCore CreateMultiCore() { return new MultiCoreA(); } }; // 工厂Bclass FactoryB : public CoreFactory { public: SingleCore CreateSingleCore() { return new SingleCoreB(); } MultiCore CreateMultiCore() { return new MultiCoreB(); } }; // 客户int main() { CoreFactory factorya = new FactoryA(); CoreFactory factoryb = new FactoryB(); //创建A型号的单核和多核 SingleCore singleCoreA = factorya->CreateSingleCore(); MultiCore multiCoreA = factorya->CreateMultiCore(); //创建B型号的单核和多核 SingleCore singleCoreB = factoryb->CreateSingleCore(); MultiCore multiCoreB = factoryb->CreateMultiCore(); return 0;}/ 输出单核A多核A单核B多核B/
单例模式(Singleton Pattern)
单例模式是最简单的设计模式之一。它涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。它保证一个类仅有一个实例,并提供一个访问它的全局访问点。由于构造函数是私有的,因此无法通过构造函数实例化,唯一的方法就是通过调用静态函数GetInstance。
优点:1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
注意事项:1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。
C++示例
单例模式的实现有多种方式,如
1、
class Singleton {public: Static Singleton Instance() { if(instance == null) { instance = new Singleton();}return instance;}private: Singleton() {} static Singleton instance;}
该方式是实现单例模式最简单的方法,但是由于它没有锁,因此不能保证多线程的安全。
2、
class Singleton {private: Singleton(){} static Singleton instance; static mutex single_mutext;public: static Singleton Instance() {single_mutext.lock();if (instance == NULL) {instance = new Singleton();}single_mutext.unlock();return instance;}};Singleton Singleton::instance = NULL;
3、饿汉式,该方式在类创建时就已经初始化,不管之后是否使用,它都占据了一块内存,因此它不需要加锁就是线程安全的。该方式实现简单且常用,在第一次使用时速度比
class Singleton {private: Singleton(){} static Singleton instance;public: static singleton Instance() { return instance; }};Singleton Singleton::instance = new Singleton();
建造者模式(Builder Pattern)
建造者模式使用多个简单的对象一步一步构建成一个复杂的对象,它将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
优点: 1、建造者独立,容易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
C++示例
汽车(Car类)按品牌分有宝马车(BMWCar类)、奔驰车(BenzCar类)等,它们由各个复杂的零配件所组成,CarBuilder类是建造者抽象类,创造产品各个部件的抽象接口,BMWCarBuilder和BenzCarBuilder是具体的建造者,创造产品各个部件的具体实现接口。建造者们通过引导者(CarDirector类)来实现一个产品的构造流程。客户只需要和Director交互获得想要的产品。
//产品基类class Car {public: string GetEngine() { return m_engine; } string GetGearBox() { return m_gearbox; } string GetChassis() { return m_chassis; } void SetEngine(string engine) { m_engine = engine; cout << "组装" << engine << endl; } void SetGearBox(string gearbox) { m_gearbox = gearbox; cout << "组装" << gearbox << endl; } void SetChassis(string chassis) { m_chassis = chassis; cout << "组装" << chassis << endl; }private: string m_engine; string m_gearbox; string m_chassis;};//宝马车产品class BMWCar : public Car {public: BMWCar() { cout << "开始组装宝马" << endl; }};//奔驰车产品class BenzCar : public Car {public: BenzCar() { cout << "开始组装奔驰" << endl; }};//建造者抽象类class CarBuilder{public: virtual Car BuildCar() = 0; virtual void BuildEngine() {} virtual void BuildGearBox() {} virtual void BuildChassis() {}};//宝马建造者具体类class BMWCarBuilder : public CarBuilder {public: BMWCarBuilder() { m_car = new BMWCar(); } void BuildEngine() { m_car->SetEngine("宝马引擎"); } void BuildGearBox() { m_car->SetGearBox("宝马变速箱"); } void BuildChassis() { m_car->SetChassis("宝马底盘"); } Car BuildCar() { return m_car; }private: Car m_car;};//奔驰建造者具体类class BenzCarBuilder : public CarBuilder {public: BenzCarBuilder() { m_car = new BenzCar(); } void BuildEngine() { m_car->SetEngine("奔驰引擎"); } void BuildGearBox() { m_car->SetGearBox("奔驰变速箱"); } void BuildChassis() { m_car->SetChassis("奔驰底盘"); } Car BuildCar() { return m_car; }private: Car m_car;};//Director 指导者class CarDirector {public: Car ConstructCar(CarBuilder carBuilder) { carBuilder->BuildEngine(); carBuilder->BuildGearBox(); carBuilder->BuildChassis(); cout << "汽车组装完毕" << endl; return carBuilder->BuildCar(); }};// 客户int main() { CarDirector carDirector; Car bmwCar = carDirector.ConstructCar(new BMWCarBuilder()); cout << endl; Car benzCar = carDirector.ConstructCar(new BenzCarBuilder());return 0;}/ 输出开始组装宝马组装宝马引擎组装宝马变速箱组装宝马底盘汽车组装完毕开始组装奔驰组装奔驰引擎组装奔驰变速箱组装奔驰底盘汽车组装完毕/
原型模式(Prototype Pattern)
原型模式用于创建重复的对象,并保证了性能。它实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。原型模式实现的关键就是实现Clone函数,在c++中即拷贝构造函数。
优点: 1、性能提高。 2、逃避构造函数的约束。
C++示例
//抽象原型类class Prototype {protected: string m_CarModel; string m_Engine;public: Prototype() {} virtual ~Prototype() {} virtual Prototype Clone() { return NULL; } virtual void Show() {}};//具体原型类 BMWclass PrototypeBMW : public Prototype {public: PrototypeBMW() { m_CarModel = string("宝马汽车"); m_Engine = string("宝马引擎"); } //拷贝构造函数 PrototypeBMW(const PrototypeBMW& bmw) { m_CarModel = bmw.m_CarModel; m_Engine = bmw.m_Engine; } ~PrototypeBMW() {} PrototypeBMW Clone() { return new PrototypeBMW(this); } void Show() { cout << m_CarModel << endl; cout << m_Engine << endl; }};// 客户int main(int argc, char argv[]){ Prototype p_car1 = new PrototypeBMW(); Prototype p_car3 = p_car1->Clone(); p_car1->Show(); //删除p_car1 delete p_car1; p_car1 = NULL; //深拷贝所以对p_car3无影响 p_car3->Show(); delete p_car3; p_car3 = NULL; return 0;}
小结
这一篇介绍了软件开发过程中23种设计模式中的创建型模式,包括工厂模式、抽象工厂模式、单例模式、建造者模式和原型模式五种,它提供了一种在创建对象的同时隐藏创建逻辑的方式,这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。在下一篇文章将对结构型模型和行为型模式进行介绍。