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

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享元模式(结构型)的更多相关文章

  1. 设计模式(11)--Flyweight(享元模式)--结构型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...

  2. Flyweight享元模式(结构型模式)

    1.面向对象的缺点 虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能.但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如 ...

  3. 设计模式(十二): Flyweight享元模式 -- 结构型模式

    说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...

  4. 设计模式之flyweight享元模式

    运用共享技术支持大量细粒度对象的使用 Flyweight模式(享元) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模 ...

  5. Flyweight 享元(结构型)

    一:描述:(该模式实际应用较少) Flyweight 享元模式是对大量细粒度的元素进行共享和重用.减少对象的创建减轻内存: 注和单例模式不同的是:享元模式的各个对象佣有各自的行为并可实例化,单例模式的 ...

  6. Java设计模式:Flyweight(享元)模式

    概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...

  7. go语言设计模式之Flyweight(享元模式)

    flyweight.go package flyweight import ( "time" ) const ( TEAM_A = "A" TEAB_B = & ...

  8. 设计模式11: Flyweight 享元模式(结构型模式)

    Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...

  9. C++设计模式-Flyweight享元模式

    Flyweight享元模式 作用:运用共享技术有效地支持大量细粒度的对象. 内部状态intrinsic和外部状态extrinsic: 1)Flyweight模式中,最重要的是将对象分解成intrins ...

随机推荐

  1. 图论(网络流,二分图最小点权覆盖):POJ 2125 Destroying The Graph

    Destroying The Graph   Description Alice and Bob play the following game. First, Alice draws some di ...

  2. 树状数组(二维):COGS 1532 [IOI2001]移动电话

    1532. [IOI2001]移动电话 ★☆   输入文件:mobilephones.in   输出文件:mobilephones.out   简单对比 时间限制:5 s   内存限制:256 MB ...

  3. 杂题 SPOJ MOBILE2 - Mobiles

    MOBILE2 - Mobiles no tags  You have been asked to buy a gift for your baby brother, Ike. However, yo ...

  4. Oracle用户管理

    创建用户 概述:在oracle中要创建一个新的用户使用create user 语句,一般是具有dba(数据库管理员)的权限才能使用. create user 用户名 identified by 密码: ...

  5. Vagrant网络配置

    Vagrant中网络配置 一.基本配置 Vagrant offers multiple options for how you are able to connect your guest machi ...

  6. Scrapy:Python的爬虫框架

    网络爬虫,是在网上进行数据抓取的程序,使用它能够抓取特定网页的HTML数据.虽然我们利用一些库开发一个爬虫程序,但是使用框架可以大大提高效率,缩短开发时间.Scrapy是一个使用Python编写的,轻 ...

  7. redis和ehcache

    Ehcache在java项目广泛的使用.它是一个开源的.设计于提高在数据从RDBMS中取出来的高花费.高延迟采取的一种缓存方案.正因为Ehcache具有健壮性(基于java开发).被认证(具有apac ...

  8. Apache Kylin

    日前,eBay公司隆重宣布已经正式向开源业界推出分布式分析引擎:Kylin(http://kylin.io).作为一套旨在对Hadoop环境下分析流程进行加速.且能够与SQL兼容性工具顺利协作的解决方 ...

  9. 表格布局TableLayout

    简单实现计算机界面布局的案例: <?xml version="1.0" encoding="utf-8"?><TableLayout xmln ...

  10. rsyslogd配置文件详解

    非常详细的rsyslogd配置文件解析 rsyslog服务和logrotate服务=========================================================== ...