《设计模式整理》

目录

    • 常见设计模式
    • 如何保证单例模式只有一个实例
    • 单例模式中的懒汉与饿汉模式
    • OOP设计模式的五项原则
    • 单例模式中的懒汉加载,如果并发访问该怎么做

常见设计模式

单例模式
单例模式主要解决了一个全局使用的类频繁的创建和销毁的问题。
单例模式下确保某一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。
单例模式有三要素:
1、某个类只能有一个实例
2、它必须自行创建这个实例
3、它必须自行向整个系统提供这个实例
优点:
1、内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
2、避免了对资源的多重占用。
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么来实例化它。
使用场景:
1、要求生产唯一序列号
2、创建一个对象消耗的资源过多,如I/O与数据库的链接等。

工厂模式
主要解决接口选择的问题。该模式下定义一个创建对象的接口,让子类自己决定实例化哪一个工厂类,
也就是让创建过程延迟到子类进行。
工厂模式的优点:
解耦,代码复用,更改功能容易。

观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,让所有依赖于它的对象都得到通知并且自动更新。
观察者模式中分为观察者和被观察者,当被观察者发生装填改变时,观察者会受到通知。
主要是为了解决对象状态改变给其他对象通知的问题,实现:类似于观察者在被观察者那边注册了一个回调函数。

装饰器模式
对于已经存在的某些类进行装饰,以此来扩展一些功能,从而动态的为一个对象增加新的功能。
装饰器模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂
使用场景:1、扩展一个类的功能 2、动态增加功能、动态撤销功能。

如何保证单例模式只有一个实例

1、将该类的构造方法定义为私有方法,这样其他处的代码无法通过调用构造函数来实例化该类的对象,只有通过类提供的静态方法来得到该类的唯一实例。
2、在该类内部提供一个静态方法,当调用这个方法时,如果类持有的引用不为空,就返回这个引用。如果类的引用为空,就创建这个类的实例。
C++的实现有两种,一种通过局部静态变量,利用其只初始化一次的特点,返回对象。另外一种,则是定义全局的指针,getInstance判断该指针是否为空,为空时才实例化对象。

单例模式中的懒汉与饿汉模式

懒汉模式:在类加载的时候不被初始化。
像一个懒汉一样,需要用到创建实例了的程序再去创建实例,不需要创建实例程序就不去创建实例,这是一个时间换空间的做法,同时体现了懒汉本性。

实现方法:定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。

#include <iostream>
#include <stdlib.h>
using namespace std;class singleton  //实现单例模式的类
{
private:singleton() //私有的构造函数,这样就不能再其他地方创建该实例{}static singleton* instance;  //定义一个唯一指向实例的指针,并且是私有的static int b; 
public:static singleton* GetInstance()  //定义一个公有函数,可以获取这个唯一实例{if (instance == NULL)  //判断是不是第一次使用instance = new singleton;return instance;}static void show(){cout << b << endl;}
};
int singleton::b = 10; //静态成员变量在类外进行初始化,它是整个类的一部分并不属于某个对象
singleton* singleton::instance = NULL;
int main()
{singleton* a1 = singleton::GetInstance();cout << a1 << endl;a1->show();singleton* a2 = singleton::GetInstance();cout << a2 << endl;a2->show();system("pause");return 0;
}

实例的两个对象的地址都是一样的
懒汉模式的singleton类有以下特点:

1、 他有一个指向唯一实例的静态指针,并且是私有的
2、它有一个公有的函数,可以获取这个唯一的实例,并且在需要的时候创建该实例
3、它的构造函数是私有的,这样就不能从别处创建该类的实例

但是这存在一个缺点,也就是说它在单线程下是正确的,但是在多线程情况下,如果两个线程同时首次调用GetInstance()方法,那么就会同时监测到instance为NULL,则两个线程会同时构造一个实例给instance,这样就会发生错误。
饿汉模式
单例类定义的时候就进行实例化
在饿汉模式中,实例对象储存在全局数据区,所以要用static来修饰,所以对于饿汉模式来说,是线程安全的,因为在线程创建之前实例就已经创建好了。

#include <iostream>
#include <stdlib.h>
using namespace std;class singleton
{
private:static singleton* instance; //这是我们的单例对象,它是一个类对象的指针singleton(){cout << "创建一个单例对象" << endl;}~singleton(){cout << "析构掉一个单例对象" << endl;}
public:static singleton* getinstance();static void deleteInstance();   //用来销毁实例
};
//下面这个静态成员变量在类加载的时候就已经初始化好了
singleton* singleton::instance = new singleton();
singleton* singleton::getinstance()
{return instance;  //直接返回inatance
}void Singleton::deleteInstance(){delete instance;
}
int main()
{cout << "we get the instance" << endl;singleton* a1 = singleton::getinstance();singleton* a2 = singleton::getinstance();singleton* a3 = singleton::getinstance();cout << "we destroy the instance" << endl;Singleton::deleteInstance();system("pause");return 0;
}

全局数据区中,存储的并不是一个实例对象,而是一个实例对象的指针,它是一个地址而已,我们真正占有资源的实例对象是存在堆中,我们需要手动的去调用delete释放申请的资源。

饿汉模式:在类加载时就完成了初始化,但是加载比较慢,获取对象比较快。
饿汉模式是线程安全的,在类创建好一个静态对象提供给系统使用。

OOP设计模式的五项原则

1、单一职责原则
避免将相同的职责分散到不同的类中。避免一个类承担太多职责。减少类的耦合,提高类的复用性。
2、接口隔离原则
使用多个专门的接口,而不是使用单一的接口。
3、开放——封闭原则
open:模块的行为必须是开放的,支持扩展的。
closed:模块在扩展时不应该影响已有的程序模块
4、替换原则
子类型必须能够替换掉他们的父类型、并且出现在父类能够出现的地方
5、依赖倒置原则
上层模块不应该依赖于下层模块,他们应该共同依赖于一个抽象。

单例模式中的懒汉加载,如果并发访问该怎么做

使用锁机制,防止多次访问。
第一次判断为空不加锁。
若为空,则进行加锁判断是否为空,若为空则生成对象。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377279.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSON学习资料整理

1.什么是JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式&#xff0c;但是也使用了类似于C语言家族的习惯&#xff08;包括C, C, C#, Java, JavaScript, Perl, Python等&#xff09;。这些…

OSI七层模型及其数据的封装和解封过程

OSI(Open System Interconnection)参考模型把网络分为七层: 1.物理层(Physical Layer) 物理层主要传输原始的比特流,集线器(Hub)是本层的典型设备; 2.数据链路层(Data Link Layer) 数据链路层负责在两个相邻节点间无差错的传送以帧为单位的数据,本层的典型设备是交换机(Switch)…

rss聚合模式案例_RSS的完整形式是什么?

rss聚合模式案例RSS&#xff1a;真正简单的联合 (RSS: Really Simple Syndication) RSS is an abbreviation of Really Simple Syndication. It is also called Rich Site Summary. It is quality attainment for the syndication of collection of web content and used to di…

《MySQL——38道查询练习(无连接查询)》

目录一、准备数据1、创建数据库2、创建学生表3、创建教师表4、创建课程表5、创建成绩表6、添加数据二、查询练习1、查询 student 表的所有行2、查询 student 表中的 name、sex 和 class 字段的所有行3、查询 teacher 表中不重复的 department 列4、查询 score 表中成绩在60-80之…

XPth和XSLT的一些简单用法

&#xff08;目的在于让大家知道有这个东西的存在&#xff09; XPath:即XML Path语言(Xpath)表达式使用路径表示法(像在URL中使用一样)来为XML文档的各部分寻址&#xff01; 关于XPath如何使用了&#xff0c;我们来看看&#xff01;当然这里面的代码只是入门&#xff0c;更深层…

isc dhcp_ISC的完整形式是什么?

isc dhcpISC&#xff1a;印度学校证书 (ISC: Indian School Certificate) ISC is an abbreviation of the Indian School Certificate. It alludes to the 12th class examination or higher secondary examination conducted by the Council for the Indian School Certificat…

《MySQL——连接查询》

内连接&#xff1a; inner join 或者 join 外连接 1、左连接 left join 或 left outer join 2、右连接 right join 或 right outer join 3、完全外连接 full join 或 full outer join 图示理解 全连接 创建person表和card表 CREATE DATABASE testJoin;CREATE TABLE person (…

win7下 apache2.2 +php5.4 环境搭建

这篇文章很好 没法复制 把链接粘贴来http://www.360doc.com/content/13/0506/13/11495619_283349585.shtml# 现在能复制了&#xff1a; 把任何一篇你要复制、却不让复制的文章收藏入收藏夹(直接CtrlD,确定) 2在收藏夹中&#xff0c;右击刚才收藏的那个网址&#xff0c;点属性 3…

运行在TQ2440开发板上以及X86平台上的linux内核编译

一、运行在TQ2440开发板上的linux内核编译 1、获取源码并解压 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源码包。 解压&#xff08;天嵌默认解压到/opt/EmbedSky/linux-2.6.30.4/中&#xff09; tar xvjf linux-2.6.30.4_20100531.tar.bz2 -C / 2、获取默认配置…

Python熊猫– GroupBy

Python熊猫– GroupBy (Python Pandas – GroupBy) GroupBy method can be used to work on group rows of data together and call aggregate functions. It allows to group together rows based off of a column and perform an aggregate function on them. GroupBy方法可用…

MySQL索引底层原理理解以及常见问题总结

目录二叉查找树为索引红黑树为索引B树作为索引B树作为索引MyISAM存储引擎索引实现InnoDB存储引擎索引实现常见问题聚集索引与非聚集索引InnoDB基于主键索引和普通索引的查询有什么区别&#xff1f;InnoDB主键索引为何是整型的自增主键何时使用业务字段作为主键呢&#xff1f;哈…

des算法密码多长_密码学中的多个DES

des算法密码多长This is a DES that was susceptible to attacks due to tremendous advances in computer hardware in cryptography. Hence, it was a very complex or competent algorithm it would be feasible to reuse DES rather than writing an of cryptography. 由于…

《MySQL——索引笔记》

目录回表覆盖索引最左前缀原则联合索引的时候&#xff0c;如何安排索引内的字段顺序&#xff1f;索引下推重建索引问题联合主键索引和 InnoDB 索引组织表问题in与between的区别回表 回到主键索引树搜索的过程&#xff0c;我们称为回表。 覆盖索引 覆盖索引就是在这次的查询中…

《操作系统知识点整理》

目录进程与线程比较多线程同步与互斥生产者与消费者哲学家就餐问题读者写者问题进程间通信管道消息队列共享内存信号量信号Socket锁互斥锁与自旋锁读写锁乐观锁与悲观锁死锁进程与线程比较 进程是资源&#xff08;包括内存、打开的文件等&#xff09;分配的单位&#xff0c;线…

操作系统大内核和微内核_操作系统中的内核

操作系统大内核和微内核A Kernel is the central component of an Operating System. The Kernel is also said to be the heart of the Operating System. It is responsible for managing all the processes, memory, files, etc. The Kernel functions at the lowest level …

《MySQL——锁》

全局锁是什么&#xff1f;全局锁有什么用&#xff1f;全局锁怎么用&#xff1f; 全局锁主要用在逻辑备份过程中&#xff0c;对于InnoDB 引擎的库&#xff0c;使用–single-transaction; MySQL 提供了一个加全局读锁的方法&#xff0c;命令是 Flush tables with read lock (FTW…

搜索引擎Constellio及Google Search Appliances connectors

做搜索产品的时候发现国外一个同类型的产品contellio&#xff0c;发现功能比较强大&#xff0c;先记录下来 貌似可以添加文档 网站 以及数据库等不同类型的数据源 http://wiki.constellio.com/index.php/Main_Page http://www.constellio.com/ http://www.constellio.com htt…

分类器是如何做检测的?——CascadeClassifier中的detectMultiScale函数解读

原地址&#xff1a;http://blog.csdn.net/delltdk/article/details/9186875 在进入detectMultiScal函数之前&#xff0c;首先需要对CascadeClassifier做初始化。 1. 初始化——read函数 CascadeClassifier的初始化很简单&#xff1a; cv::CascadeClassifier classifier; cl…

abs std::abs_ABS的完整形式是什么?

abs std::absABS&#xff1a;防抱死制动系统 (ABS: Anti-lock Braking System) ABS is an abbreviation of the Anti-lock Braking System. It is a safety anti-skid braking system that is used on a variety of aircraft, automobiles and other land vehicles, such as mo…

汉字速查使用方法简介

《汉字速查》&#xff08;HanziSearcher&#xff09;是一个支持全汉字字典和词典的检索工具。其界面如下所示。 界面上方为工具栏。 左方为字典和词典检索栏。 右方在启动时显示版权信息和作者的联系方式&#xff0c;在执行检索时&#xff0c;显示检索结果。 检索方法 汉字速查…