设计模式
学习笔记之C++设计模式——创建型模式 📑 [【设计模式】[【设计模式】结构型模式|结构型模式
📑 [【设计模式】[【设计模式】行为型模式|行为型模式
一、工厂模式
简单工厂模式
代码
#include <iostream>
#include "main.h"
using namespace std;
/*
定义一个水果抽象类。供具体水果实现,和工厂使用
*/
class Fruit {
public:
virtual void getName() = 0;
};
class APPLe : public Fruit{
public:
virtual void getName() {
cout << "我是苹果" << endl;
}
};
class Banana : public Fruit {
public:
virtual void getName(){
cout << "我是香蕉" << endl;
}
};
//抽象的工厂类
class AbstractFactory
{
public:
virtual Fruit * createFruit() = 0;
};
//通过具体的某一产品的工厂生产某种产品
class AppleFactory : public AbstractFactory
{
public:
virtual Fruit * createFruit() {
return new Apple;
}
};
class BananaFactory : public AbstractFactory
{
public:
virtual Fruit * createFruit() {
return new Banana;
}
};
int main()
{
//来一个香蕉工厂
AbstractFactory * bananaFactory = new BananaFactory;
//给我来一个水果
Fruit * banana = bananaFactory->createFruit();
banana->getName();
delete bananaFactory;
delete banana;
AbstractFactory * appleFactory = new AppleFactory;
Fruit * apple = appleFactory->createFruit;
apple->getName();
system("pause");
return 0;
}类图
工厂模式的优缺点
优点
- 不需要记住具体类名,甚至连具体参数都不用记忆。
- 实现了对象创建和使用的分离。
- 系统的可扩展性也就变得个非常好,无需修改接口和原类。
缺点
-
增加系统中类的个数,复杂度和理解度增加。
-
增加了系统的抽象性和理解难度。
二、抽象工厂模式
工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产-产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,我们可以考虑将一些相关的产品组成一个”产品族”, 由同-个工厂来统-生产,这就是我们本文将要学习的抽象工厂模式的基本思想。
图例
代码
#include <iostream>
#include "main.h"
using namespace std;
//抽象产品类 供具体产地产品实现
class AbstractApple {
public:
virtual void getName() = 0;
};
class AbstractBanana {
public:
virtual void getName() = 0;
};
class AbstractPear {
public:
virtual void getName() = 0;
};
class USAApple : public AbstractApple {
public:
virtual void getName() {
cout << "美国苹果" << endl;
}
};
class ChinaApple : public AbstractApple {
public:
virtual void getName() {
cout << "中国苹果" << endl;
}
};
class JapanApple : public AbstractApple {
public:
virtual void getName() {
cout << "日本苹果" << endl;
}
};
class USABanana : public AbstractBanana {
public:
virtual void getName() {
cout << "美国香蕉" << endl;
}
};
class ChinaBanana : public AbstractBanana {
public:
virtual void getName() {
cout << "中国香蕉" << endl;
}
};
class JapanBanana : public AbstractBanana {
public:
virtual void getName() {
cout << "日本香蕉" << endl;
}
};
class USAPear : public AbstractPear {
public:
virtual void getName() {
cout << "美国鸭梨" << endl;
}
};
class ChinaPear : public AbstractPear {
public:
virtual void getName() {
cout << "中国鸭梨" << endl;
}
};
class JapanPear : public AbstractPear {
public:
virtual void getName() {
cout << "日本鸭梨" << endl;
}
};
//抽象的工厂类,供具体产品族的实现
class AbstractFactory {
public:
virtual AbstractApple * creatApple() = 0;
virtual AbstractBanana * creatBanana() = 0;
virtual AbstractPear * creatPear() = 0;
};
//具体的工厂
class USAFactory : public AbstractFactory {
public:
virtual AbstractApple * creatApple() {
return new USAApple;
}
virtual AbstractBanana * creatBanana() {
return new USABanana;
}
virtual AbstractPear * creatPear() {
return new USAPear;
}
};
class ChinaFactory : public AbstractFactory {
public:
virtual AbstractApple * creatApple() {
return new ChinaApple;
}
virtual AbstractBanana * creatBanana() {
return new ChinaBanana;
}
virtual AbstractPear * creatPear() {
return new ChinaPear;
}
};
class JapanFactory : public AbstractFactory {
public:
virtual AbstractApple * creatApple() {
return new JapanApple;
}
virtual AbstractBanana * creatBanana() {
return new JapanBanana;
}
virtual AbstractPear * creatPear() {
return new JapanPear;
}
};
int main()
{
//现在要准备一个 中国的苹果,中国的香蕉
AbstractApple *AA = NULL;
AbstractBanana *AB = NULL;
AbstractPear *AP = NULL;
AbstractFactory *factory = NULL;
factory = new ChinaFactory;
//中国的苹果
AA = factory->creatApple();
//中国的香蕉
AB = factory->creatBanana();
AP = factory->creatPear();
AA->getName();
AB->getName();
AP->getName();
delete AA;
delete AB;
delete AP;
delete factory;
system("pause");
return 0;
}抽象工厂模式不符合“开闭原则”
抽象工厂模式的优缺点
优点:
- 拥有工厂方法模式的优点
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象
- 增加新的产品族很方便,无需修改已有系统,符合“开闭原则”。
缺点:
- 增加新的产品结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,带来较大的不便,违背了“开闭原则”。
抽象模式的应用:可以自己写一个计算机产品相关
简单工厂模式 + “开闭原则” = 工厂方法模式
工厂方法模式 + “产品族” = 抽象工厂模式
简单工厂模式(规模较小的模型)
工厂方法模式(中等)
抽象工厂模式(复杂的)
借鉴了《Easy搞定设计模式》
三 单例模式
保证一个类、只有一个实例存在,同时提供能对该实例加以访问的的全局访问方法。
三个要点:
一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。

角色和职责
Singleton(单例):在单例类的内部实现只生成一个实例,同时是他提供一个静态的getInstance()方法,让客户可以访问他的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。
单例模式的使用步骤
- 构造函数私有化
- 提供一个全局的静态方法(全局访问点) 来获取单例对象。
- 在类中定义一个静态指针,指向本类的变量的静态变量指针
饿汉模式
理解
主要就是为了只让类只有一个实例而把构造函数私有化。定义一个全局的静态实例。
代码
#include <iostream>
using namespace std;
/*
三个步骤:
1.构造函数私有化(为了不让在类的外部再创建多余的实例)
2.提供一个全局的静态类指针指向唯一实例
3.提供一个全局的静态函数获取实例
*/
class Singleton {
public:
// 静态类函数 返回静态实例
static Singleton * getInstance() {
return instance;
}
private:
//不让类的外部创建实例
Singleton() {
Singleton *single = getInstance();
}
Singleton getsingle() {
}
static Singleton * instance; //指向本类的唯一实例指针
};
//静态类变量在类外初始化
Singleton*Singleton::instance = new Singleton;
int main()
{
//通过getInstance()获取实例
Singleton * s1 = Singleton::getInstance();
system("pause");
return 0;
}懒汉模式
在程序执行期间再去判断是否需要实例。
class Singleton1 {
public:
//提供一个返回实例的方法
static Singleton1 * getInstance() {
// 不确定程序在编译期间是否需要实例
// 如果是多线程下,需要在这里加锁
if (instance1 == NULL) {
instance1 = new Singleton1;
}
// 释放锁
cout << "Singleton1" << endl;
return instance1;
}
private:
Singleton1() {
}
static Singleton1 *instance1;
};
//懒汉式的初始化方式 饿汉式在初始化时已经指向了singleton
Singleton1 * Singleton1::instance1 = NULL;针对单例模式去判断是否是同一实例
Singleton *s1 = Singleton::getinstace();
Singleton *s2 = Singleton::getinstace();
if (s1 == s2 )
cout << "s1 == s2" << endl;
else
cout << "s1 != s2" << endl;单例模式的应用——打印机
用单例模式实现一个打印机程序,用以记录打印的次数和内容
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Printer {
public:
static Printer * getinstance() {
return instance;
}
void print(string text) {
cout << "打印的内容为:" << text << endl;
sequence++;
cout << "打印机今天使用了" << sequence << "次" << endl;
}
static int getSequence() {
return sequence;
}
private:
// 定义一个类去析构单例
class Garbo {
private:
~Garbo() {
if (instance != NULL) {
delete instance;
}
}
};
static Garbo garbo; // 在静态区域开辟一个对象,Garbo
static int sequence;
static Printer * instance;
};
int Printer::sequence = 0;
Printer *Printer::instance = new Printer;
Printer::Garbo Printer::garbo;
int main()
{
//三个peple使用打印机
Printer * p1 = Printer::getinstance();
p1->print("亿封简历");
Printer *p2 = Printer::getinstance();
p2->print("一份工作汇报");
Printer *p3 = Printer::getinstance();
p3->print("离职申请");
system("pause");
return 0;
}以上就是几种常见的创建型设计模式。