GeekBand C++ C++设计模式 第九周笔记

来源:互联网 发布:笑声软件下载 编辑:程序博客网 时间:2024/06/07 07:43

  如第八周所说,这周得内容是说设计模式的体验和思考。为什么要使用设计模式呢?参考书依然是《设计模式精解-GoF 23种设计模式解析》

  设计模式可以比作于面向对象分析和设计中的道路。最终表达出来的应该是一种想法和指导。而这些应该是在系统开发中所需要的。那么为什么要使用设计模式呢?这次整理的内容以书中所说的Singleton模式举例来说。

  以全局变量来说,在纯面向对象支持的编程语言(C#、JAVA等)中,可以理解为没有全局变量的概念来继续工作。但对于C++这样子支持面向过程的语言似乎就不合适。在作设计的时候实际上要好好综合考虑,为什么要使用这种设计模式,也就是要防止滥用设计模式的情况。Singleton模式可能可以说是最简单的设计模式了,其应用的场景和示例实在是没有太多可以再重复,但是以下的两个问题还是需要进一步的思考:

  1:Singleton模式 VS 全局变量。很多情况下,使用Singleton模式达到的效果和全局变量达到的效果类似。但是,全局变量不能防止实例化多个对象。《设计模式》中给出了Singleton模式的意图“保证一个类仅有一个对象,并提供一个访问它的全局访问点”,因此全局变量可以达到后面半句的效果,但是却不能保证仅有一个对象被实例化。另外,使用全局变量将使得对象在无论是否用到都要被创建,而Singleton模式则没有这个瑕疵。

  2:Singleton的子类化问题。一般来说Singleton的子类并不是Singleton,因此在保证Singleton的正确子类化,在实现上要注意几点。i.父类Singleton的构造函数为Protected,目的是为了要让Singleton子类访问,而不让Client程序访问(防止被其他方式实例化类);Singleton子类构造函数声明为private或者protected,并且将父类Singleton声明为子类Singleton的友元,目的是在父类Singleton中可以实例化子类Singleton,而Client程序不可访问(防止被其他方式实例化类)。ii.必须改写父类Singleton中的Instance方法(获得唯一实例方法)。因为Instance是static的成眼函数,不能以多态的方式实现之。必须在父类Singleton中就是提供真正实例化Singleton子类的信息。可以通过到某一个专门的地方获取Singleton子类的信息,例如提供一个获取函数,在Instance实例化Singleton子类之前获得这个信息,再根据这个信息去实例化具体的Singleton子类。

  示例代码:

//Singleton.h#ifndef _SINGLETON_H_#define _SINGLETON_H_#include <iostream>using namespace std;class Singleton{public:static Singleton* Instance();virtual void PrintInfo();protected:Singleton();private:static Singleton* _instance;};class SingletonDeriveA:public Singleton{private:friend class Singleton;SingletonDeriveA();public:virtual ~SingletonDeriveA();void PrintInfo();};class SingletonDeriveB:public Singleton{private:friend class Singleton;SingletonDeriveB();public:virtual ~SingletonDeriveB();void PrintInfo();};char* GetSingletionType();#endif //~_SINGLETON_H_//Singleton.cpp#include "Singleton.h"#include <ctime> //for time#include <iostream>using namespace std;Singleton* Singleton::_instance = 0;Singleton::Singleton(){cout<<"Singleton...."<<endl;}Singleton* Singleton::Instance(){const char* type = GetSingletionType();if (_instance == 0){if (strcmp(type,"SingletonDeriveA") == 0){_instance = new SingletonDeriveA();}else if (strcmp(type,"SingletonDeriveB")== 0){_instance = new SingletonDeriveB();}else{_instance = new Singleton();}}return _instance;}void Singleton::PrintInfo(){cout<<"Singleton type:Singleton"<<endl;}SingletonDeriveA::SingletonDeriveA(){cout<<"SingletonDeriveA...."<<endl;}SingletonDeriveA::~SingletonDeriveA(){}void SingletonDeriveA::PrintInfo(){cout<<"Singleton type:SingletonDeriveA"<<endl;}SingletonDeriveB::SingletonDeriveB(){cout<<"SingletonDeriveB...."<<endl;}SingletonDeriveB::~SingletonDeriveB(){}void SingletonDeriveB::PrintInfo(){cout<<"Singleton type:SingletonDeriveB"<<endl;}char* GetSingletionType(){//随机返回一个Singleton子类srand((unsigned int)time(NULL));int SINGLETON_TYPE = rand() % 3;switch (SINGLETON_TYPE){case 0:return "SingletonDeriveA";break;case 1:return "SingletonDeriveB";break;case 2:return "Singleton";break;default :return "Singleton";break;}}//main.cpp#include "Singleton.h"#include <iostream>using namespace std;int main(int argc,char* argv[]){for (int i = 0; i < 10; ++i){Singleton* sgn = Singleton::Instance();sgn->PrintInfo();}//Singleton* sgn1 = new SingletonDeriveA(); //compile error,保证不能通过其他方式实例化类return 0;}
  由于GetSingletionType()实现策略不是很好,运行后10次返回的随机数取模后的结果是一样的,因此获得Singleton对象是一样的,但是不同时刻运行的结果可以不一样。

  关于设计模式的思考:1.设计模式强调的是思想,而不是一门技术。设计模式实在应该属于面向对象分析和设计的范畴,和实际的编码关联反而很小。通过对设计模式的学习,慢慢体会和理解什么是系统,程序的分析和设计。2.设计模式指导怎样去创建、维护、分配面向对象系统中的实体类,以获得高内聚、低耦合的面向对象系统,从而提高系统的可维护性和可复用性。



0 0
原创粉丝点击