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

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. Light OJ 1027 - A Dangerous Maze(概率)

    题目大意: 你在一个迷宫里,你面前有n个门,你选择门的概率是一样的,每扇门有一个数字k, 加入这个数字是负数,那么这个门会花费你abs(k)分钟后把你带回原点, 假如这个数字是正数,他可以把你带出迷宫 ...

  2. 【转】Android 菜单(OptionMenu)大全 建立你自己的菜单--不错

    原文网址:http://www.cnblogs.com/salam/archive/2011/04/04/2005329.html 菜单是用户界面中最常见的元素之一,使用非常频繁,在Android中, ...

  3. HDOJ(HDU) 2401 Baskets of Gold Coins(数列、)

    Problem Description You are given N baskets of gold coins. The baskets are numbered from 1 to N. In ...

  4. Vagrant网络配置

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

  5. 武汉Uber优步司机奖励政策(1月18日~1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. 你应该知道的8个Java牛人

    简单介绍一下8个Java牛人,他们为Java社区,创建了框架(framework),产品或者是写书,影响甚至改变了Java开发的方法 8.Tomcat创始人 James Duncan Davidson ...

  7. dubbo源码分析二:服务发布

    本文将深入分析dubbo的服务发布涉及到的流程及主要类的代码.首先,我们先从类的关系图来看一下dubbo发布服务涉及到的相关类. 1.类图 上图展示了部分服务发布过程中需要使用到的类和接口,其中: s ...

  8. TCP/UDP 、HTTP、IP 、socket 的关系。

    网络有上下分为7 层.物理层,数据链路层.网络层.会话层.应用层.传输层: IP协议位于网络层,IP和端口来控制网络流向: TCP.UDP是基于传输层.TCP保证三次握手.传递数据: UDP为不考虑是 ...

  9. [转] Form表单中method="post/get'的区别

    Form提供了两种数据传输的方式——get和post.虽然它们都是数据的提交方式,但是在实际传输时确有很大的不同,并且可能会对数据产生严重的影响.虽然为了方便的得到变量值,Web容器已经屏蔽了二者的一 ...

  10. SSL证书制作

    1.创建根证书秘钥文件(自己做CA)root.key: openssl genrsa -out root.key -aes256 2048 2.创建根证书的申请文件root.csr openssl r ...