面向对象设计模式之Flyweight享元模式(结构型)
动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价。如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?
意图:运用共享技术有效地支持大量细粒度的对象。
UML图解:

Flyweight模式现实中的应用:
1.现行的博客、企业、商务网站中其网站的代码本质上是一样的,不一样的只是具体的数据和模板而代码核心和数据库却是共享的;所以现行的做法是将每个用户的博客或网站整合到一个网站中,共享其相关的代码和数据,这样对于硬盘、内存、CPU、数据库空间等服务器资源都可以达成共享,减少服务器资源的浪费,而对于代码,由于是一份实例,维护和扩展都更加容易;
2.再比如,.NET下字符串string 对象的也是运用了Flyweight模式,string a="享元设计模式";string b="享元设计模式";Object.ReferenceEquals(a,b);返回结果是true;
3.像围棋、五子棋、跳棋等等,它们都有大量的棋子对象,而它们的内部状态(如颜色,大小)都是恒定的; 而外部状态(坐标)却是变化的,就围棋而论,一盘棋理论上有361个空位可以放棋子,如果用常规的面向对象方式编程,每盘棋可能有两三百个棋子对象产生,一台服务器就很难支持更多的玩家玩围棋游戏了,所以,现行的设计是采用享元设计模式解决这种服务器空间有限问题,采用此设计模式至少棋子对象可以减少到只有两个实例。
示例:以五子棋游戏为例;代码如下
namespace Flyweight
{
/// <summary>
/// 抽象棋子类
/// </summary>
public abstract class Chess
{
Color color;
public string nickName { get; set; } /// <summary>
/// 棋子颜色
/// </summary>
public Color Color
{
get { return color; }
} /// <summary>
/// 棋子名称
/// </summary>
public string NickName
{
get { return nickName; }
} protected Chess(Color c, string nickname)
{
color = c;
nickName = nickname;
} /// <summary>
/// 在棋盘上画出自身
/// </summary>
/// <param name="p"></param>
/// <param name="radius"></param>
public abstract void Draw(Point p, int radius); } /// <summary>
/// 五子棋
/// </summary>
public class FiveChess:Chess
{
public FiveChess(Color c,string name)
: base(c, name)
{ } public override void Draw(Point p, int radius)
{
//画五子棋代码实现....
}
} /// <summary>
/// 生产五子棋棋子工厂类
/// </summary>
public static class FiveChessFactory
{
private static Hashtable chessTable = new Hashtable(); public static Chess GetChess(Color key)
{
if (!chessTable.ContainsKey(key))
{
chessTable.Add(key, new FiveChess(key,key.Name+"方"));
}
return (Chess)chessTable[key];
}
} /// <summary>
/// 客户程序
/// </summary>
public class FiveChessGame
{
public static void Main()
{
//红方VS黑方 可以将坐标位置用两个集合来储存,用来判断输赢
FiveChessFactory.GetChess(Color.Red).Draw(new Point(5, 5), 3);
FiveChessFactory.GetChess(Color.Black).Draw(new Point(5, 10), 3); FiveChessFactory.GetChess(Color.Red).Draw(new Point(5, 0), 3);
FiveChessFactory.GetChess(Color.Black).Draw(new Point(5,15 ), 3); FiveChessFactory.GetChess(Color.Red).Draw(new Point(10,5 ), 3);
FiveChessFactory.GetChess(Color.Black).Draw(new Point(20, 5), 3);
//这样无论红方和黑方下多少棋子,只有红棋子和黑棋子两个具体实例对象,大大降低了系统的消耗 }
}
}
Flyweight模式的几个要点:
1、面向对象很好滴解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
2、Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体 实现方面,要注意对象状态的处理
3、对象的数量太大从而导致对象内存开销大——什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断
面向对象设计模式之Flyweight享元模式(结构型)的更多相关文章
- 设计模式(11)--Flyweight(享元模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...
- Flyweight享元模式(结构型模式)
1.面向对象的缺点 虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能.但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如 ...
- 设计模式(十二): Flyweight享元模式 -- 结构型模式
说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...
- 设计模式之flyweight享元模式
运用共享技术支持大量细粒度对象的使用 Flyweight模式(享元) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模 ...
- Flyweight 享元(结构型)
一:描述:(该模式实际应用较少) Flyweight 享元模式是对大量细粒度的元素进行共享和重用.减少对象的创建减轻内存: 注和单例模式不同的是:享元模式的各个对象佣有各自的行为并可实例化,单例模式的 ...
- Java设计模式:Flyweight(享元)模式
概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...
- go语言设计模式之Flyweight(享元模式)
flyweight.go package flyweight import ( "time" ) const ( TEAM_A = "A" TEAB_B = & ...
- 设计模式11: Flyweight 享元模式(结构型模式)
Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...
- C++设计模式-Flyweight享元模式
Flyweight享元模式 作用:运用共享技术有效地支持大量细粒度的对象. 内部状态intrinsic和外部状态extrinsic: 1)Flyweight模式中,最重要的是将对象分解成intrins ...
随机推荐
- 路由器刷机常见第三方固件及管理前端种类(OpenWrt、Tomato、DD-Wrt)
目前路由器折腾刷机,除了采用各品牌的原厂固件外,第三方路由器固件,基本就是:Tomato.DD-WRT.OpenWRT三种. 基本上所有第三方路由器固件的架构上可分为前端(Frontend)和后端(B ...
- Rational Rose与UML教程
在学UML的过程中,Rational Rose的角色无比重要.现在能找到的大多数是2003的,但下面连接是2007. http://blog.csdn.net/skl_TZ/article/detai ...
- Spring MVC返回对象JSON
@RestController 用于返回对象,会自动格式化为JSON @RequestMapping("/user2") public User2 user2(Mo ...
- STRUCTS 2 LABLE
{LJ?Dragon}[标题]structs2标签的作用 {LJ?Dragon}[Diary]2017年,愉快的开始:离别不一定总伤感,虽然只是安慰着自己......... 问与答 问题 在Strut ...
- js输入框只能输入数字和小数点
<input name="number" onKeyPress="if (event.keyCode!=46 && (event.keyCode&l ...
- 斜堆,非旋转treap,替罪羊树
一.斜堆 斜堆是一种可以合并的堆 节点信息: struct Node { int v; Node *ch[]; }; 主要利用merge函数 Node *merge(Node *x, Node *y) ...
- Mono For Android离线激活
我们之前创建过Mono For Android的开发环境,但是使用一段时间后就说明证书过期,那如何破解呢? 但我说的这个也就只能使用免费的证书. 首先下载免费的证书,monoandroid.licx, ...
- [Javascript] Grouping and Nesting Console Log Output
Organize your log output by grouping your logs into collapsable hierarchies using console.group(). ; ...
- sizeof操作符-结构体与类大小
导读 sizeof是C/C++一个难点,当在自定义类上应用sizeof操作符时,总会出现意想不到的结果,下面,我们就来探讨一下sizeof这个操作符! 目录 1. sizeof与strlen的区别 2 ...
- discuz! X3.2 自定义后台门户模块模板里的标签
这里只提供对源码的修改, 至于插件, 暂不考虑... 想在首页里展示一些自定义字段的内容, 奈何dz无此功能, 无奈去扒源码. 首先切到 source 文件夹下 1. 在 class/block/po ...