主要是看着http://www.mscenter.edu.cn/blog/k_eckel 学习,有代码并且23种设计模式总结的很好~
我自己简单记点笔记。
设计模式:用一个通用模式可以解决一类问题,一个框架
一创建型模式:
Factory, AbstractFactory,Singleton,Builder,Prototype
这里面试测试岗位最常问到要求写的就是singleton单例设计模式,C++primer Plus中也有提到
所谓单例设计模式,是想定义一个只能被实例化一次的类, 这个具体化后的对象相当于是面向对象编程中的一个全局变量(全局变量不符合面向对象编程的要求)。
实现:将构造函数放在protected或private中,使得外部不能利用construct构造对象。唯一的途径是利用public static的成员函数调用保护的构造成员函数,但static成员函数保证了只能执行一次,生成一个唯一的类对象。
code:
1 1 #ifndef SINGLETON__H_INCLUDED 2 2 #define SINGLETON__H_INCLUDED 3 3 #include <iostream> 4 4 5 5 /*Singleton 单例设计模式,构造函数放在private或protected中 6 6 通过public的静态成员函数调用construct,static函数只在第一次调用时执行,所以单例模式 7 7 只生成一个实例*/ 8 8 9 9 using namespace std; 10 10 class Singleton 11 11 { 12 12 public: 13 13 static Singleton* Instance(); 14 14 protected: 15 15 Singleton(); 16 16 private: 17 17 static Singleton *_instance; 18 18 }; 19 19 20 20 #endif // SINGLETON__H_INCLUDED 21 21 //------------------------------------------------------------------ 22 22 #include "Singleton.h" 23 23 #include <iostream> 24 24 25 25 using namespace std; 26 26 27 27 Singleton * Singleton::_instance=0; // 28 28 29 29 Singleton::Singleton() 30 30 { 31 31 cout<<"Singleton"<<endl; 32 32 } 33 33 34 34 Singleton* Singleton::Instance() 35 35 { 36 36 if(_instance==0) 37 37 { 38 38 _instance=new Singleton(); 39 39 } 40 40 return _instance; 41 41 } 42 42 //--------------------------------------------------------- 43 43 #include <iostream> 44 44 #include "Singleton.h" 45 45 using namespace std; 46 46 47 47 int main() 48 48 { 49 49 Singleton* sgn=Singleton::Instance();// public 50 50 51 51 return 0; 52 52 }
Factory,AbstractFactory
工厂模式就像它的名字一样,好比车床加工模具一样,一台车床可以加工出各式各样的模具,操作工人不需要知道代码怎么写的,甚至不关心加工出来的是个啥,只要负责站在流水线上就可以了(这个比方不知道恰当否)
用面向系统设计的专业术语来讲,
1)为了提高内聚(Cohesion)和松耦合(Coupling) ,我们经常会抽象出一些类的公共接口以形成抽象基类或借口。即一个基类factory指针可以指向多个派生类,具体生产哪个product由concreteFactory决定(Factory和AbstractFactory的区别就是:Factory模式只有一个concreteFactory生产同一类产品【A1,A2...】,而AbstractFactory模式有多个factory的子类,不同的子类生产一些相关但不同类的产品【A1,A2...】,【B1,B2,...】,...)。客户需要用的是已经封装好的factory接口就可以了,不能了解生产工艺。
2)这里1)中为什么不直接factory中生产product呢,而是在下面又扩展了一层?我觉得应该是考虑到AbstractFactory要生产A大类,B大类多类product,就需要Factory_A,Factory_B,考虑到代码的重复利用和管理维护,用个基类Factory管理派生这些子类,无疑更方便。
PS:高内聚(Cohesion)和松耦合(Coupling):
耦合是指两个实体相互依赖于对方的一个量度;内聚(Cohesion)是一个模块内部各成分之间相关联程度的度量
Q:什么叫高内聚 低耦合?
A;系统的各个模块尽可能具有较大的独立性,换句话说,希望这样设计软件结构,使得每个模块完成一个相对独立的特定子功能,并且和其他模块之间的关系很简单,以便能方便地把不同场合下写成的程序模块组合成软件系统。衡量模块独立性的定性标准是内聚(一个模块内各个元素彼此结合的紧密程度)和耦合(一个软件结构内不同模块之间互连程度的度量)。高内聚、低耦合的模块是设计时追求的目标。尽量降低系统各个部分之间的耦合度,是应用服务层设计中需要重点考虑的问题。
简单来讲就是类似属性的东西隔一个模块里边,并且保证各个模块相对独立,即插即用~~
code:
1 // Product.h 2 3 4 #ifndef _PRODUCT_H_ 5 #define _PRODUCT_H_ 6 7 class Product 8 { 9 public: 10 virtual ~Product()=0; 11 protected: 12 Product(); 13 }; 14 15 class ConcreteProduct:public Product 16 { 17 public: 18 ConcreteProduct(); 19 ~ConcreteProduct(); 20 }; 21 22 #endif 23 //----------------------------------------------------- 24 // Factory.h 25 /*Factory两个重要功能: 26 1,高内聚,松耦合,Factory类中提供一个接口,,并封装了product类的实例化。 27 2,具体化的工作延迟至Factory子类中进行 28 (Product可能有很多子类,Factory中不知道要实例化哪一个 29 但是Factory的对应的子类知道需要创建哪一个产品)。 30 31 */ 32 #ifndef _FACTORY_H_ 33 #define _FACTORY_H_ 34 35 class Product; //前向声明Product是一个类 36 37 class Factory 38 { 39 public: 40 virtual ~Factory()=0; 41 virtual Product* GetProduct()=0; 42 protected: 43 Factory(); //把创建对象放在子类中实现 44 }; 45 46 class ConcreteFactory:public Factory 47 { 48 public: 49 ConcreteFactory(); 50 ~ConcreteFactory(); 51 Product* GetProduct(); 52 }; 53 54 #endif 55 //---------------------------------------------------- 56 #include "Product.h" 57 #include <iostream> 58 59 using namespace std; 60 61 Product::Product() 62 { 63 cout<<"Product.."<<endl; 64 } 65 Product::~Product() 66 { 67 } 68 ConcreteProduct::ConcreteProduct() 69 { 70 cout<<"ConcreteProduct.."<<endl; 71 } 72 73 ConcreteProduct::~ConcreteProduct() 74 { 75 // ... 76 } 77 //-------------------------------------- 78 #include "Factory.h" 79 #include "Product.h" 80 #include <iostream> 81 82 using namespace std; 83 84 Factory::Factory() 85 { 86 cout<<"Factory.."<<endl; 87 } 88 Factory::~Factory() 89 { 90 } 91 92 ConcreteFactory::ConcreteFactory() 93 { 94 cout<<"ConcreteFactory.."<<endl; 95 } 96 ConcreteFactory::~ConcreteFactory() 97 { 98 99 } 100 Product* ConcreteFactory::GetProduct() 101 { 102 return new ConcreteProduct(); 103 } 104 //-------------------------------------------------------- 105 # include "Factory.h" 106 #include <iostream> 107 108 using namespace std; 109 110 int main() 111 { 112 Factory* spd=new ConcreteFactory();//父类Factory不知道要实例化Product的哪一个子类 113 Product* p=spd->GetProduct();// 114 return 0; 115 }
Bulider建设者模式:
如果说Factory只关心结果,Builder模式的话更关心过程,最后生成Product实例之前需要做一些别的工作(Factory直接返回Product或其子类的实例),这些工作A,B,C可能会影响到product实例的生成,就像一点意外就会导致人的一生戏剧性的转变,这个也是这样的道理。当然A,B,C这些类方法需要有一些Director提供的参数控制,使最后product生成的是director而不是actor什么的。
Prototype模式:
这个就是一个类拷贝的过程,自定义一个复制构造函数和重载赋值操作符。