学习记录:《C++设计模式——李建忠主讲》5.“对象性能”模式
对象性能模式:面向对象很好地解决了抽象地问题,但是必不可免地要付出一定地代价。对于通常情况来讲,面向对象地成本大都可以忽略不计,但某些情况,面向对象所带来地成本必须谨慎处理。
典型模式:单件模式(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:
- 定义一个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.“对象性能”模式的更多相关文章
- 学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式
状态变化模式:在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定.状态变化模式为这一问题提供了一种解决方案. 典型模式:状态模式(State).备忘录 ...
- 学习记录:《C++设计模式——李建忠主讲》1.设计模式
1.学习目标 1)理解松耦合设计思想: 2)掌握面向对象设计原则: 3)掌握重构技法改善设计: 4)掌握GOF核心设计模式: 2.定义 每个设计模式描述了一个在我们周围不断重复发生的问题,以及该问题解 ...
- 学习记录:《C++设计模式——李建忠主讲》2.面向对象设计原则
1.课程内容: 重新认识面向对象:面向对象设计原则: 2.重新认识面向对象 1)理解隔离变化:从宏观层面来看,面向对象的构建方式更能适应软件的变化,将变化所带来的影响减为最小: 2)各司其职:从微观层 ...
- 学习记录:《C++设计模式——李建忠主讲》3.“组件协作”模式
“组件协作”模式:现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式.典型模式:Template M ...
- 学习记录:《C++设计模式——李建忠主讲》4.“单一职责”模式
单一职责模式:在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式:装饰模式(Decorator).桥 ...
- 学习记录:《C++设计模式——李建忠主讲》7.“领域规则”模式
领域规则模式:在特定领域中,某些变化虽然频繁,但可以抽象为某种规则.这时候,结合特定的领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案. 典型模式:解释器模式(Interpreter). ...
- 工厂模式(整理自李建忠<C++设计模式>视频)
整理自李建忠<C++设计模式>视频 一.导入:"对象创建"模式和工厂模式 工厂模式只是该模式下的一种. 二.举例说明 有这样一个场景:需要在MainForm中设计一个按 ...
- 设计模式---对象性能模式之单例模式(Singleton)
前提:“对象性能”模式 面向对象很好的解决了“抽象”的问题,但是必不可免地要付出一定的代价.对于通常情况来讲,面向对象的成本大都可以忽略不计.但是某些情况,面向对象所带来的成本必须谨慎处理. 前面是 ...
- C++设计模式 之 “对象性能” 模式:Singleton、Flyweight
“对象性能”模式 面向对象很好地解决了“抽象”的问题,但是必不可免地要付出一定的代价.对于通常情况来讲,面向对象的成本大都可以忽略不计.但是某些情况,面向对象所带来的成本必须谨慎处理. 典型模式 # ...
随机推荐
- Uipath 勾选checkbox
东京IT青年前线 http://www.rpatokyo.com/ Uipath 勾选checkbox 使用check Activity可以对check box 复选框进行勾选. 虽然Click也可以 ...
- java集合第一节,List简单介绍
Java中List集合的常用方法 List接口是继承Collection接口,所以Collection集合中有的方法,List集合也继承过来. package 集合; import java.ut ...
- .NET Core System.Drawing.Common 中文乱码的坑
最近在写一个汉字取点阵的程序,最开始是在win环境下运行的,没发现什么异常,然后今天把程序放在centos 下后发现英文正常,中文完全变成两位的字了,最开始是字体的原因 在把宋体等安装到centos ...
- jquery 往上滚动的时显示,上下滚动执行的js
$(document).on("mousewheel DOMMouseScroll", function (e) { var delta = (e.originalEvent.wh ...
- The usage of Markdown---杂谈:缩进/换行/分割线/注释/文字颜色
目录 1. 序言 2. 缩进 3. 换行 4. 分割线 5. 注释 6. 改变文字大小和颜色 更新时间:2019.09.14 1. 序言 今天一口气更新了接近10篇博客(虽然只是将我之前基本码好的 ...
- lamda和匿名内部类
匿名内部类 匿名内部类在日常编程中还是经常会使用的.比如 ArrayList<String> list=new ArrayList<>(); list.add(new Stri ...
- SpringBoot整合MybatisPlus3.X之自定义Mapper(十)
pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId& ...
- github实用的搜索小技巧
查资源,学习优秀的框架,搜索是一种能力! 作为程序猿开发中最大的同性交友网站,github当之无愧,里面有很多优秀的开源框架,各种技术大佬混迹其中,有他们总结的学习教程,造好的轮子(开发的各种工具,技 ...
- Hbase与Oracle的比较
http://blog.csdn.net/lucky_greenegg/article/details/47070565 转自:http://www.cnblogs.com/chay1227/arch ...
- go语言版本测试, 一段错误代码引发的血案
起因: 最近在学习手写docker,看到了一段会编译错误的代码. 过程: 最近在学习docker,看到一段示例代码,每次编译时会报错. 因此, 无法继续下去, 只好在网上搜索解决方案, 用了很多时间, ...