二、单例模式、建造者模式、原型模式(没写完) 享元模式 (没写完)

单例模式(singleton)

保证一个类只有一个实例存在,提供对该实例加以访问的全局访问方法

实现:

  1. 构造函数私有化
    防止别的地方调用
  2. 提供一个全局的静态方法
  3. 类中有一个静态指针,指向该类类型
    让类负责保存他唯一的实例。

这里隐含的含义是,程序知道这个类只能被这样实例化。

代码

// ./Singleton.h
class Singleton
{
private:
  Singleton()=default;
  static Singleton *_instance;
public:
  static Singleton *instance();
  static bool freeInstance();
}

// ./Singleton.cc
#include "Singleton.h"


//惰性模式,不访问不创建,在第一次访问的时候创建
//对静态变量的初始化必需放在类的外部
Singleton Singleton::*_instance=nullptr;
Singleton Singleton::*instance()
{
  if(_instance=nullptr)
  {
    _instance = new Singleton();
  }
  return _instance; 
}
//
//非惰性模式
//在程序一运行就进行了初始化
Singleton Singleton::*_instance=new Singleton();
Singleton Singleton::*instance()
{
  return _instance; 
}
//
bool Singleton::freeInstance()
{
  if(_instance!=nullptr)
  {
    delete _instance;
    _instance=nullptr;
  }
}

使用

#include "Singleton.h"
int main()
{
  Singleton *p=Singleton::instance();
  //....
  return 0;
}

单例模式与多线程

惰性单例模式由于其实例初始化的方式,会导致在多线程中可能创建多个实例,所以其构造函数不是一种线程安全的函数。
因此如果使用惰性模式,需要使用互斥量。

"单例"模式

单例模式的类,可以不止有一个实例,如果一个类需要几个特定类型,或者需要的某种类型的实例的数量只需要一个。
那么可以不使用_instance存储,改为map<string,Singleton*>即可。

建造者模式

对象的构建太复杂
将对象的表示与构建分离

例如,有一些类在创建的时候,需要传大量的参数,还可能某一下参数是选填的。
并且还可能,这个类的实例创建出来以后,还有一些字段需要填。
那么如果只是用构造函数,那么这个逻辑,这个构造函数,可能会很臃肿。
也有一些字段可能就那么几种,也就是说有那么一个模板。

啥?你说怎么可能有这样的类?
人员管理啊,名字,地址,联系方式,这些是必填的选项吧。邮箱,老婆,女朋友,这些事选填的吧。万一以后又要加上工资这个字段,咋办?还是用构造函数?
不现实啊。

设计模式是将问题的解决方法标准化的方法,再加上解耦,这个本来就复杂的问题,变得更加复杂了。嗯~~

UML

建造者模式

代码

//人员
class ClerkDetail
{
public:
  clerkDetail()=default;
  clerkDetail(string name);      //表示必填的字段
  string sex();                  //下面的是字段的设置和获取选项,使用了重载。
  void sex(string s);
  int age();
  void age(int i);
private:
  string _name;
  string _sex;                   //下面两个表示选填的字段
  int      _age;
};

//模板继承的基类
class abClerkTplt
{
  virtual void sex();      //这两个是抽象的借口,t他们没有参数
  virtual void age();        //因为其子类,将根据子类所指示的那种模板设置参数。
  virtual ClerkDetail* getclerk();
};

//人员的一些模板
class ManClerk:pubilc:abClerkTplt
{
public: 
  ManClerk()
  {
    _clerk=new ClerkDetail;
  }
  virtual void sex()
  {
    _clerk->set("man");
  }
  virtual void  age()
  {
    _clerk->age(17);
  }
  virtual ClerkDetail* getclerk()
  {
    return _clerk;
  }
private:
  ClerkDetail *_clerk;
};

//人员的一些模板,这里还是一个模板
class WomanClerk:pubilc:abClerkTplt
{
  //....
};

//一个执行模板子类的类。
class createClerk
{
public:
  createClerk(abClerkTplt* Tplt)
  {
    _tplt=tplt;
  }
  vodi create()
  {
    tplt->age();
    tplt->sex();
  }
private:
  abClerkTplt* _tplt;
};

//使用
int main()
{
  abClerkTplt* manTplt=new ManClerk;
  createClerk   dir(manTplt);
  dir.crete();
  ClerkDetail *clerk1=manTplt->getClerk();
}

这个模式过于复杂。应该是可以简化的吧。比如createClerk这个类,应该可以去掉吧。
以后再想想。

原型模式

类能够提供一个能够复制自身的接口

复制自身则涉及到深拷贝和浅拷贝。
在复制指针类型时,如果之复制指针那么就是浅拷贝:两个指针指向相同的地址,容易造成二次释放。(多次释放同一块内存的地址)
复制指针的时候,复制指针复制地址的内容,在内存中开辟新的内存空间,而不是复制指针内容,称为深拷贝:没啥问题。
浅拷贝好比复制顶层。而深拷贝复制底层。

原型模式时,类自身提供一个clone()接口,返回自身类型的指针。就这么简单
复制的时候,要么使用默认构造函数,创建一个临时对象,要么使用拷贝构造函数。

UML

代码

class AbPerson
{
public:  
  virtual AbPerson *clone()=0;
}

class Clerk:public:AbPerson
{
public:
  Clerk();
  Clerk(&clerk c)
  {
    //这里可以直接复制的就直接复制
    i=this.i;
    //c因为是个指针。不能够直接复制,需要分配内存。
    c=this.cloneC();
  }
  virtual AbPerson *clone()
  {
    //转发给拷贝构造函数,让拷贝构造函数干活
    return new Clerk(*this)
  }
private:
  int i;
  char *c;
  char *cloneC()//这里可以放一个函数,用来复制C,有几个指针,就有几个这种函数。
   {

  }
}

这一部分回头看看书。。。深拷贝+拷贝构造函数有点蒙了。

既然有了拷贝构造函数,那么为什么还需要原型模式?
拷贝构造函数只能复制自身。
而原型模式的基类提供了一种可以复制自身的方法,并且返回基类的指针。

拷贝构造函数为原型模式提供了实现。

享元模式

使用共享对象可有效的支持大量细粒度的对象

享元模式:共享不变的那部分元素。
如果系统需要创建大量的元素,而这些元素某一部分特征又是相同的,另一部分与有自己的特征。

比如,别人都提到的文本编辑器,每个字符可共享的部分就是字符本身,特征部分是字符的字号,颜色。
比如黑白棋,棋子可共享,但是有黑白和位置之分。

享元模式将一个对象划分为可变部分和不可变部分,该类型对象的数量并没介绍反而增加了。但是系统中总的对象数量确实是减少了。程序所占内存减少。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容