设计模式 --> (10)享元模式
享元模式
运用共享技术有效地支持大量细粒度的对象。
享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)。
内蕴状态是存储在享元对象内部并且不会随环境改变而改变。因此内蕴状态并可以共享。
外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态与内蕴状态是相互独立的。
适用性:
1.当系统中有大量的细粒度对象实例,而且这些对象实例中有一些属性是重复的情况下,考虑使用。
2.文本编辑器,输入法之类的常用应用。
优点:
1.提高了系统的效率,减小了内存的消耗。
2.减少了重复代码。
3.减少了系统的复杂度。
缺点:
1.维护共享对象和查找所需的共享对象需要花费很多时间。
举例
举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子。现在要实现一个围棋程序,该怎么办呢?首先要考虑的是棋子棋盘的实现,可以定义一个棋子的类,成员变量包括棋子的颜色、形状、位置等信息,另外再定义一个棋盘的类,成员变量中有个容器,用于存放棋子的对象。
在围棋中,棋子就是大量细粒度的对象。其属性有内在的,比如颜色、形状等,也有外在的,比如 在棋盘上的位置。内在的属性是可以共享的,区分在于外在属性。因此,可以这样设计,只需定义两个棋子的对象,一颗黑棋和一颗白棋,这两个对象含棋子的内在 属性;棋子的外在属性,即在棋盘上的位置可以提取出来,存放在单独的容器中。相比之前的方案,现在容器中仅仅存放了位置属性,而原来则是棋子对象。显然, 现在的方案大大减少了对于空间的需求。
#include <iostream>
#include <vector>
using namespace std; //棋子颜色
enum PieceColor {BLACK, WHITE}; //棋子位置
struct PiecePos
{
int x;
int y;
PiecePos(int a, int b): x(a), y(b) {}
}; //棋子定义
class Piece
{
protected:
PieceColor m_color; //颜色
public:
Piece(PieceColor color): m_color(color) {}
~Piece() {}
virtual void Draw() {}
}; //黑棋
class BlackPiece: public Piece
{
public:
BlackPiece(PieceColor color): Piece(color) {}
~BlackPiece() {}
void Draw() { cout<<"绘制一颗黑棋\n"; }
}; //白棋
class WhitePiece: public Piece
{
public:
WhitePiece(PieceColor color): Piece(color) {}
~WhitePiece() {}
void Draw() { cout<<"绘制一颗白棋\n";}
}; //棋盘
class PieceBoard
{
private:
vector<PiecePos> m_vecPos; //存放棋子的位置
Piece *m_blackPiece; //黑棋棋子
Piece *m_whitePiece; //白棋棋子
string m_blackName;
string m_whiteName;
public:
PieceBoard(string black, string white): m_blackName(black), m_whiteName(white)
{
m_blackPiece = NULL;
m_whitePiece = NULL;
}
~PieceBoard() { delete m_blackPiece; delete m_whitePiece;}
void SetPiece(PieceColor color, PiecePos pos)
{
if(color == BLACK)
{
if(m_blackPiece == NULL) //只有一颗黑棋
m_blackPiece = new BlackPiece(color);
cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";
m_blackPiece->Draw();
}
else
{
if(m_whitePiece == NULL)
m_whitePiece = new WhitePiece(color);
cout<<m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";
m_whitePiece->Draw();
}
m_vecPos.push_back(pos);
}
}; int main()
{
PieceBoard pieceBoard("A","B");
pieceBoard.SetPiece(BLACK, PiecePos(, ));
pieceBoard.SetPiece(WHITE, PiecePos(, ));
pieceBoard.SetPiece(BLACK, PiecePos(, ));
pieceBoard.SetPiece(WHITE, PiecePos(, ));
}
参考 http://blog.csdn.net/wuzhekai1985
设计模式 --> (10)享元模式的更多相关文章
- python设计模式之享元模式
python设计模式之享元模式 由于对象创建的开销,面向对象的系统可能会面临性能问题.性能问题通常在资源受限的嵌入式系统中出现,比如智能手机和平板电脑.大型复杂系统中也可能会出现同样的问题,因为要在其 ...
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- 设计模式(C#)——10享元模式
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 前言 在软件开发中,当我们需要对某些对象重复创建,且最终只需要得到单一结果.如果使用一般思维,那我们将浪费很多内存空 ...
- 【GOF23设计模式】享元模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_享元模式.享元池.内部状态.外部状态.线程池.连接池 package com.test.flyweight; /** * ...
- 设计模式之享元模式(Flyweight)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 【设计模式】享元模式(Flyweight)
摘要: 1.本文将详细介绍享元模式的原理和实际代码中特别是Android系统代码中的应用. 纲要: 1. 引入享元模式 2. 享元模式的概念及优缺点介绍 3. 享元模式在Android源码中的应用 1 ...
- 【php设计模式】享元模式
享元模式其实就是共享独享模式,减少重复实例化对象的操作,从而将实例化对象造成的内存开销降到最低. 享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象.我们将通过创建 5 个对象来画出 ...
- 【UE4 设计模式】享元模式 Flyweight Pattern
概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...
- JS常用的设计模式(16)—— 享元模式
享元模式主要用来减少程序所需的对象个数. 有一个例子, 我们这边的前端同学几乎人手一本<JavaScript权威指南>. 从省钱的角度讲, 大约三本就够了. 放在部门的书柜里, 谁需要看的 ...
- Head First设计模式之享元模式(蝇量模式)
一.定义 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. ...
随机推荐
- arm_linux_device_mem内存映射
/dev/mem: 物理内存的全镜像.可以用来访问物理内存. /dev/kmem: kernel看到的虚拟内存的全镜像.可以用来访问kernel的内容. /dev/mem 用来访问物理IO设备比如X ...
- HI3531网络tftp、nfs加载
ifconfig eth0 hw ether 00:00:23:34:45:66; ifconfig eth0 192.168.1.10 netmask 255.255.255.0; route a ...
- mpeg文件格式分析
MPEG-1流比特层次结构分析总结 1.简要介绍Mpeg 2.Mpeg-1数据流分析 2.1视频序列层(VideoStream) 2.2画面组层(GOP) 2.3画面层(Pictures) 2.4片层 ...
- js中百分比运算,大型数据会算错
改法:被除数乘100在做除法运算,就能改掉算错
- Angular通过订阅观察者对象实现不同组件中数据的实时传递
在angular官方定义中,组件直接的数据交换只要在父子直接传递,但是我们在项目中经常需要在各种层级之间传递数据,下面介绍关于订阅可观察对象实现的数据传递. 首先定义一个服务app.sevice.ts ...
- luogu【P2753】[USACO4.3]字母游戏Letter Game
这个题...一开始看了很久题目(并且问了机房几个大佬)才明白题意.. (原题入口) 题意 大概是一开始给你一些字母出现的次数 你之后组成的单词(最多两个单词)每个字母出现次数 必须小于或等于标准(st ...
- 踩坑の SpringMVC文件上传
环境准备 添加两个jar包 commons-fileupload-1.2.2.jar commons-io-2.4.jar 配置要求 在springmvc.xml中配置multipart类型解 ...
- 【2016北京集训测试赛】river
HINT 注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式. [吐槽] 嗯..看到这题的想法的话..先想到了每个点的度为2,然后就有点不知所措了 隐隐约约想到了网络流,但并没 ...
- 基于python创建一个简单的HTTP-WEB服务器
背景 大多数情况下主机资源只有开发和测试相关人员可以登录直接操作,且有些特定情况"答辩.演示.远程"等这些场景下是无法直接登录主机的.web是所有终端用户都可以访问了,解决了人员权 ...
- Java中常见数据结构List之LinkedList
二,LinkedList 1, linkedList底层数据结构 linkedList底层是一个双向链表 2,LinkedList和ArrayList的对比 1.顺序插入速度ArrayList会比较快 ...