对象性能模式:面向对象很好地解决了抽象地问题,但是必不可免地要付出一定地代价。对于通常情况来讲,面向对象地成本大都可以忽略不计,但某些情况,面向对象所带来地成本必须谨慎处理。

典型模式:单件模式(Singleton)、共享模式(Flyweight)。

一、单件模式

1.动机

在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。

2.作用

绕过常规构造器,提供一种机制来保证一个类只有一个实例(设计者的责任)。

3.定义

保证一个类仅有一个实例,并提供一个该实例的全局访问点。

4.代码

//单件模式实现
class Singleton{
private:
Singleton();
Singleton(const Singleton& other);
public:
static Singleton* getInstance();
static Singleton* m_instance;
};
Singleton* Singleton::m_instance=nullptr;
//线程非安全版本
Singleton* Singleton::getInstance() {
if (m_instance == nullptr) {
m_instance = new Singleton();
}
return m_instance;
}
//线程安全版本,但锁的代价过高
Singleton* Singleton::getInstance() {
Lock lock;
if (m_instance == nullptr) {
m_instance = new Singleton();
}
return m_instance;
}
//双检查锁,但由于内存读写reorder不安全(这里不详细解释reorder情形)
Singleton* Singleton::getInstance() {
if(m_instance==nullptr){
Lock lock;
if (m_instance == nullptr) {
m_instance = new Singleton();
}
}
return m_instance;
}

 5.解析

对于一些类来说,只有一个实例是很重要的。比如:虽然系统中可以由许多打印机,但却只应该由一个打印假脱机;只应该有一个文件系统和窗口管理器;一个数字滤波器只能有一个A/D转换器;一个会计系统只能专用于一个公司。这应该是类设计者的责任,而不是使用者的责任。

在上述代码中,线程非安全版本对单线程程序是安全的,但对多线程是不安全的;对于线程安全版本,通过加“锁”使多线程安全,但锁的代价过高(针对只读情况);对于双检查锁,在“锁”之前先检查也提高效率,降低代价。

6.结构

Singleton:

  1. 定义一个Instance操作,允许客户访问它的唯一实例;Instance是一个类操作;

2.可能负责创建自己唯一的实例。

7.总结

1.Singleton模式中的实例构造器可以设置为protected以允许子类派生。

2.Singleton模式一般不要支持拷贝构造函数和Clone接口,因为这有可能导致多个对象实例,与Singleton模式的初衷违背。

3.实现多线程环境下安全的Singleton,注意对双检查锁的正确实现。

二、共享模式

1.动机

在软件系统采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价。

2.作用

避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作。

3.定义

运用共享技术有效地支持大量细粒度地对象。

4.代码

//运用共享模式
class Font {
private:
string key;
public:
Font(const string& key){
//...
}
};
class FontFactory{
private:
map<string,Font* > fontPool;
public:
Font* GetFont(const string& key){
map<string,Font*>::iterator item=fontPool.find(key);
if(item!=footPool.end()){
return fontPool[key];
}
else{
Font* font = new Font(key);
fontPool[key]= font;
return font;
}
}
void clear(){
}
};

 5.解析

享元模式对那些通常因为数量太大而难以用对象来表示的概念或实体进行建模。例如,文档编辑器可以为每一个字母创建一个Flyweight,每个Flyweight存储一个字符代码。每次需要调用Flyweight对象时,用户不用直接对其进行实例化,而是通过FlyweightFactory对象得到ConcreteFlyweight对象(创建前先判断该对象是否存在,如果存在,直接返回;如果不存在,则创建该对象,并将其放入对象池,最后返回。),这样保证对它们适当进行共享。

 6.结构

7.总结

1.面向对象很好地解决了抽象性问题,但作为一个运行在机器上地程序实体,我们需要考虑对象地代价问题。Flyweigh主要主要解决面向对象地代价问题,不触及抽象性问题。

2.Flyweigh采用对象共享地做法来降低系统中对象地个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。

3.对象的数量太大从而导致对象内存开销加大——数量大小需要根据具体应用情况评估。

学习记录:《C++设计模式——李建忠主讲》5.“对象性能”模式的更多相关文章

  1. 学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式

    状态变化模式:在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定.状态变化模式为这一问题提供了一种解决方案. 典型模式:状态模式(State).备忘录 ...

  2. 学习记录:《C++设计模式——李建忠主讲》1.设计模式

    1.学习目标 1)理解松耦合设计思想: 2)掌握面向对象设计原则: 3)掌握重构技法改善设计: 4)掌握GOF核心设计模式: 2.定义 每个设计模式描述了一个在我们周围不断重复发生的问题,以及该问题解 ...

  3. 学习记录:《C++设计模式——李建忠主讲》2.面向对象设计原则

    1.课程内容: 重新认识面向对象:面向对象设计原则: 2.重新认识面向对象 1)理解隔离变化:从宏观层面来看,面向对象的构建方式更能适应软件的变化,将变化所带来的影响减为最小: 2)各司其职:从微观层 ...

  4. 学习记录:《C++设计模式——李建忠主讲》3.“组件协作”模式

    “组件协作”模式:现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式.典型模式:Template M ...

  5. 学习记录:《C++设计模式——李建忠主讲》4.“单一职责”模式

    单一职责模式:在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式:装饰模式(Decorator).桥 ...

  6. 学习记录:《C++设计模式——李建忠主讲》7.“领域规则”模式

    领域规则模式:在特定领域中,某些变化虽然频繁,但可以抽象为某种规则.这时候,结合特定的领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案. 典型模式:解释器模式(Interpreter). ...

  7. 工厂模式(整理自李建忠<C++设计模式>视频)

    整理自李建忠<C++设计模式>视频 一.导入:"对象创建"模式和工厂模式 工厂模式只是该模式下的一种. 二.举例说明 有这样一个场景:需要在MainForm中设计一个按 ...

  8. 设计模式---对象性能模式之单例模式(Singleton)

    前提:“对象性能”模式  面向对象很好的解决了“抽象”的问题,但是必不可免地要付出一定的代价.对于通常情况来讲,面向对象的成本大都可以忽略不计.但是某些情况,面向对象所带来的成本必须谨慎处理. 前面是 ...

  9. C++设计模式 之 “对象性能” 模式:Singleton、Flyweight

    “对象性能”模式 面向对象很好地解决了“抽象”的问题,但是必不可免地要付出一定的代价.对于通常情况来讲,面向对象的成本大都可以忽略不计.但是某些情况,面向对象所带来的成本必须谨慎处理. 典型模式 # ...

随机推荐

  1. mysql 二十余种报错注入姿势

    1.floor()  floor 和group by 搭配使用 利用group by 的key唯一性 和mysql 编码执行顺序导致二次执行产生不同key ))) ) 数值型注入时 不用闭合‘  进行 ...

  2. 本月16日SpringBoot2.2发布,有哪些变化先知晓

    本月(2019年10月16日)Spring Boot 2.2已经正式发布了!在此篇文章中,将给大家介绍一下2.2版为大家带来了哪些重要的新变化.笔者用心书写,希望阅读完成之后转发关注,你的支持是我不竭 ...

  3. 小白终于弄懂了:c#从async/await到Task再到Thread

    1. 为什么会有/怎么解决: async/await的无限嵌套 public async Task<int> myFuncAsync1() { //some code int num = ...

  4. 5.分析snkrs的Android的DeviceID生产规则

    分析Android的DeviceID生产 前面已经把web端的分析了一些,要想实现其实容易也难,容易是规则很容易,难是时间生成控制很难,我之前大概花了一周时间分析和梳理,然后行为测试,之前我已经讲过c ...

  5. boostrap原理.html

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. WebSocket原理及技术简介

    摘要: WebSocket用于在Web浏览器和服务器之间进行任意的双向数据传输的一种技术.WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程.其目的是在We ...

  7. Python 中的反射方法

    一.概述 getattr # 根据字符串为参数,去对象中找与之同名的成员. hasattr # 根据字符串为参数,去判断对象中是否有与之同名的成员. setattr # 根据字符串为参数,动态的设置一 ...

  8. EXCEL批量导入到Sqlserver数据库并进行两表间数据的批量修改

    Excel 大量数据导入到sqlserver生成临时表并将临时表某字段的数据批量更新的原表中的某个字段 1:首先要对EXCEL进行处理 列名改成英文,不要有多余的列和行(通过ctrl+shift 左或 ...

  9. vsftpd超实用技巧详解

    简介: vsftpd是"very secure FTP daemon"的缩写,是一个完全免费的.开放源代码的ftp服务器软件. 工作原理: vsftpd使用ftp协议,该协议属于应 ...

  10. 五、docker-compose开锋(docker 三剑客)

    前言 终于写到docker-compose了,其实我最开始接触docker的时候,是因为一个开源项目需要用docker 环境和docke-compose 所以我最先接触的是docker-compse ...