现在在大力推行节约型社会,“浪费可耻,节俭光荣”。在软件系统中,有时候也会存在资源浪费的情况,例如,在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高。那么,是否存在一种技术可以用于节约内存使用空间,实现对这些相同或者相似对象的共享访问呢?答案是肯定的,这种技术就是享元模式。

一 享元模式概述

1.1 享元模式简介

享元(Flyweight)模式:运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,是一种结构型模式。

1.2 享元模式需求

  M公司开发部欲开发一个围棋软件,其界面效果如下图所示:

  M公司开发人员通过对围棋软件进行分析,发现在围棋棋盘中包含大量的黑子和白子,它们的形状、大小都一模一样,只是出现的位置不同而已。如果将每一个棋子都作为一个独立的对象存储在内存中,将可能导致该围棋软件在运行时所需要的内存空间较大。

  如何降低运行代价、提高系统性能是M公司开发人员需要解决的一个问题。为此,M公司开发人员决定使用享元模式来设计该软件。

1.3 类图

  

1.4 代码实现

1.4.1 抽象棋子类

#pragma once

#include <string>
#include <iostream>
using namespace std;
class AbstractPiece
{
public:
AbstractPiece(){}
~AbstractPiece(){} virtual string GetColor() = ;
virtual void Display(CCoordinates *pCoodinates) = ;
};

1.4.2 白色棋子类

class WritePiece : public AbstractPiece
{
public:
WritePiece()
{
cout << "WritePiece Construct" << endl;
}
~WritePiece()
{
cout << "WritePiece Deconstruct" << endl;
} string GetColor()
{
return "white";
} void Display(CCoordinates *pCoodinates)
{
cout << "棋子颜色:"<< GetColor() << "," <<
"棋子坐标:" << pCoodinates->m_x << "," << pCoodinates->m_y << endl;
}
};

1.4.5 黑色棋子类

class BlackPiece : public AbstractPiece
{
public:
BlackPiece()
{
cout << "BlackPiece Construct" << endl;
}
~BlackPiece()
{
cout << "BlackPiece Deconstruct" << endl;
} string GetColor()
{
return "black";
} void Display(CCoordinates *pCoodinates)
{
cout << "棋子颜色:"<< GetColor() << "," <<
"棋子坐标:" << pCoodinates->m_x << "," << pCoodinates->m_y << endl;
}
};

1.4.6 棋子外部状态类

class CCoordinates
{
public:
CCoordinates(int x, int y)
{
m_x = x;
m_y = y;
}
~CCoordinates(){} public:
int m_x;
int m_y;
};

1.4.7 棋子工厂类(单例)

#pragma once

#include "flyweight.h"
#include <map>
using namespace std; class CPieceFactor
{
private:
CPieceFactor();
~CPieceFactor(); public:
//static CPieceFactor* GetPieceFactorInstance();
static AbstractPiece* CreatePiece( string strColor );
private:
typedef map<string, AbstractPiece*> PIECEMAP;
static PIECEMAP m_PieceVect;
static CPieceFactor *m_pPieceFactor;
};
#include "PieceFactor.h"

// 饥饿模式的单例模式
CPieceFactor::PIECEMAP CPieceFactor::m_PieceVect;
CPieceFactor * CPieceFactor::m_pPieceFactor = new CPieceFactor();
CPieceFactor::CPieceFactor()
{
AbstractPiece *pWrite = new WritePiece();
m_PieceVect.insert(make_pair<string, AbstractPiece*>("write", pWrite));
AbstractPiece *pBlack = new BlackPiece();
m_PieceVect.insert(make_pair<string, AbstractPiece*>("black", pBlack));
} CPieceFactor::~CPieceFactor()
{
PIECEMAP::iterator iter;
for (iter = m_PieceVect.begin(); iter != m_PieceVect.end(); iter ++)
{
delete iter->second;
}
} AbstractPiece* CPieceFactor::CreatePiece( string strColor )
{
return m_PieceVect[strColor];
}

1.5 测试

#include "stdio.h"

#include "PieceFactor.h"

void main()
{
// 通过享元工厂获取3颗黑子
AbstractPiece *pPiece1 = CPieceFactor::CreatePiece("black");
AbstractPiece *pPiece2 = CPieceFactor::CreatePiece("black");
AbstractPiece *pPiece3 = CPieceFactor::CreatePiece("black"); string strCmp;
strCmp = pPiece1 == pPiece2 ? "相同":"不相同";
cout << "判断两颗黑子是否相同:" << strCmp.c_str() <<endl; // 通过享元工厂获取2颗白子
AbstractPiece *pPiece4 = CPieceFactor::CreatePiece("write");
AbstractPiece *pPiece5 = CPieceFactor::CreatePiece("write");
strCmp = pPiece1 == pPiece2 ? "相同":"不相同";
cout << "判断两颗白字是否相同:" << strCmp.c_str() <<endl; // 显示棋子
pPiece1->Display(new CCoordinates(,));
pPiece2->Display(new CCoordinates(, ));
pPiece3->Display(new CCoordinates(, ));
pPiece4->Display(new CCoordinates(, ));
pPiece5->Display(new CCoordinates(, )); return;
}

二 享元模式总结

2.1 主要优点

  可以极大减少内存中对象的数量,使得相同或相似对象在内存中只有一份 => 节省系统资源,提高系统性能!棒棒哒!

2.2 主要缺点

  为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长!

2.3 应用场景

  (1)一个系统有大量相同或相似的对象,造成了系统内存的大量损耗 => 赶紧使用享元模式吧!

  (2)对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。

  (3)要维护享元模式,需要耗费一定的系统资源,因为在需要时会多次重复使用才值得使用享元模式了!

设计模式之享元(flyweight)模式的更多相关文章

  1. python 设计模式之享元(Flyweight)模式

    #写在前面 这个设计模式理解起来很容易.百度百科上说的有点绕口. #享元模式的定义 运用共享技术来有効地支持大量细粒度对象的复用. 它通过共享已经存在的对橡大幅度减少需要创建的对象数量.避免大量相似类 ...

  2. Java 实现享元(Flyweight)模式

    /** * 字母 * @author stone * */ public class Letter { private String name; public Letter(String name) ...

  3. 十二、享元(Flyweight)模式--结构模式(Structural Pattern)

    Flyweight在拳击比赛中指最轻量级,即"蝇量级",有些作者翻译为"羽量级".这里使用"享元 模式"更能反映模式的用意. 享元模式以共享 ...

  4. 设计模式C++描述----12.享元(Flyweight)模式

    一. 概述 在面向对象系统的设计何实现中,创建对象是最为常见的操作. 这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销.特别是对于大量轻量级(细粒度)的对象,比如在文档编辑 ...

  5. 享元(FlyWeight)模式

    享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式.享元模式尝试 ...

  6. 十一、结构模式之享元(Flyweight)模式

    什么是享元模式 享元模式是对象的结构模式,是运用共享技术来有效的支持大量细粒度的对象.享元对象能做到共享的关键是区分内蕴状态和外蕴状态.一个内蕴状态是存储在享元对象内部,并且是不会随环境改变而有所不同 ...

  7. 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)

    原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...

  8. 设计模式:享元(FlyWeight)模式

    设计模式:享元(FlyWeight)模式 一.前言     享元(FlyWeight)模式顾名思义,既是轻量级的,原因就是享元,共享元素,这里的元素指的是对象.如何共享对象,那就是在检测对象产生的时候 ...

  9. python设计模式之享元模式

    python设计模式之享元模式 由于对象创建的开销,面向对象的系统可能会面临性能问题.性能问题通常在资源受限的嵌入式系统中出现,比如智能手机和平板电脑.大型复杂系统中也可能会出现同样的问题,因为要在其 ...

  10. JAVA设计模式之享元模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述享元(Flyweight)模式的: Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是 ...

随机推荐

  1. 使用阿里的maven库

    快使用阿里云的maven仓库 自从开源中国的maven仓库挂了之后就一直在用国外的仓库,慢得想要砸电脑的心都有了.如果你和我一样受够了国外maven仓库的龟速下载?快试试阿里云提供的maven仓库,从 ...

  2. poj 3253超时

    哈夫曼树超时是因为每次都需要重排,十分浪费时间,即使是快排.

  3. Hibernate 菜鸟教程 异常 集锦

    异常1.Error parsing JNDI name [foo] 异常信息摘要: org.hibernate.engine.jndi.JndiException: Error parsing JND ...

  4. 详解Linux系统中的文件名和文件种类以及文件权限

    Linux文件种类与副文件名 一直强调一个概念,那就是:任何装置在Linux底下都是文件, 不仅如此,连资料沟通的介面也有专属的文件在负责-所以,你会瞭解到,Linux的文件种类真的很多- 除了前面提 ...

  5. Linux下多线程下载工具MWget和Axel使用介绍

    linux运维在操作linux过程中,用得最多的linux下载工具想必一定是wget,没有看到哪一台服务器没装过wget的,或许有人使用ftp下载,也有人使用多线程的axel以及ProZilla,毫无 ...

  6. struts2——文件下载自定义文件名,包括中文

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  7. 介绍几个C#正则表达式工具

    这里将为大家推荐介绍几个C#正则表达式工具,这些小工具能帮助大家在.NET开发过程中起到事半功倍的效果,希望大家喜欢. 推荐三个C#正则表达式工具,理由如下 第一个C#正则表达式工具,REGEX 这个 ...

  8. MFC--自定义CMFCTabCtrl的实现

    在MFC实现桌面程序时,可能会用到TabView效果,我实现的是最基本的效果,如下图: 下面介绍详细的实现过程,如果需要效果更好看些,自行美化. 1.  创建自定义MFCTabCtrl类MyMFCTa ...

  9. Mac环境下Android Studio配置Git以及最基本使用

    Git是分布式版本管理工具,现在使用十分广泛,相对于SVN,GIT的使用更加方便,在离线环境下,仍然可以进行版本控制工作.且速度十分快.在Windows下,先需要自行安装Git程序,网址git-scm ...

  10. day5-python中的序列化与反序列化-json&pickle

    一.概述 玩过稍微大型一点的游戏的朋友都知道,很多游戏的存档功能使得我们可以方便地迅速进入上一次退出的状态(包括装备.等级.经验值等在内的一切运行时数据),那么在程序开发中也存在这样的需求:比较简单的 ...