设计模式
学习笔记之C++设计模式——创建型模式
📑 【设计模式】结构型模式
📑 【设计模式】行为型模式
一、工厂模式
简单工厂模式
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #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 ; }
类图
工厂模式的优缺点
优点
不需要记住具体类名,甚至连具体参数都不用记忆。
实现了对象创建和使用的分离。
系统的可扩展性也就变得个非常好,无需修改接口和原类。
缺点
增加系统中类的个数,复杂度和理解度增加。
增加了系统的抽象性和理解难度。
二、抽象工厂模式
工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产-产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销 。此时,我们可以考虑将一些相关的产品组成一个"产品族”, 由同-个工厂来统-生产,这就是我们本文将要学习的抽象工厂模式的基本思想。
图例
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 #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
类型的静态对象,作为外部共享的唯一实例。
单例模式的使用步骤
构造函数私有化
提供一个全局的静态方法(全局访问点) 来获取单例对象。
在类中定义一个静态指针,指向本类的变量的静态变量指针
饿汉模式
理解
主要就是为了只让类只有一个实例而把构造函数私有化。定义一个全局的静态实例。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> using namespace std;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 () { Singleton * s1 = Singleton::getInstance (); system ("pause" ); return 0 ; }
懒汉模式
在程序执行期间再去判断是否需要实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Singleton1 {public : static Singleton1 * getInstance () { if (instance1 == NULL ) { instance1 = new Singleton1; } cout << "Singleton1" << endl; return instance1; }private : Singleton1 () { } static Singleton1 *instance1; }; Singleton1 * Singleton1::instance1 = NULL ;
针对单例模式去判断是否是同一实例
1 2 3 4 5 6 Singleton *s1 = Singleton::getinstace (); Singleton *s2 = Singleton::getinstace ();if (s1 == s2 ) cout << "s1 == s2" << endl;else cout << "s1 != s2" << endl;
单例模式的应用——打印机
用单例模式实现一个打印机程序,用以记录打印的次数和内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #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; static int sequence; static Printer * instance; };int Printer::sequence = 0 ; Printer *Printer::instance = new Printer; Printer::Garbo Printer::garbo;int main () { Printer * p1 = Printer::getinstance (); p1->print ("亿封简历" ); Printer *p2 = Printer::getinstance (); p2->print ("一份工作汇报" ); Printer *p3 = Printer::getinstance (); p3->print ("离职申请" ); system ("pause" ); return 0 ; }
以上就是几种常见的创建型设计模式。