场景:程序需要不断创建大量相似的细粒度对象,会造成严重的内存负载。我们可以选择享元模式解决该问题。

享元抽象:Flyweight 描述享元的抽象结构。它包含内蕴和外蕴部分(别被术语迷惑,这是一种比较深的描述,浅的来说,内蕴就是对象中不变的数据,外蕴反之,在编程时区分两者的区别就可以了,无需刻意在代码中表达这种术语的含义。)

享元:ConcreteFlyweight 可用用来共享的对象实例,我们将享元的按照共享性质分为内蕴(不因环境变化而变的部分),外蕴两部分。内蕴是享元的固有特性,不会变化。外蕴需要享元被调用时由外部设置。

享元池(或叫享元工厂):FlyweightFactory存放享元的地方。

非共享享元:UnsharedFlyweight 与享元都继承自享元抽象,但其不能被共享。其应用在需要将一个享元组合一起使用,并统一设置外蕴的情景。比如为了提高执行速度,将经常重复出现的对象组(其中每个对象也可以是从享元池中共享抽取出来的)封装到一起,从而执行重复的工作。比如说制图中,由几个基本形状组成的复合形状需要经常被提取出来执行绘制操作。

模型图如下:

示例:

//在一个任务中客户需要绘制大量的正方形
 //其中这些正方形在填充颜色和尺寸上仅有有限的几个固定值。
 //边长是5,10,15,颜色,红,绿,蓝,这代表客户端需求按边长,颜色分组最多有3*3=9组类似的正方形对象。

//如果每次需要一个正方形对象,其中每个对象关于填充颜色的数据很大,如果都要一一实例化,将会是内存读写,负载不断增大。

//如果采用享元模式,在享元池中最多存放9种不同内蕴的实例。那么将大大减少内存负载。

//经常会出现一些同样的组合形状被重复绘制
 //为了提高运行效率,可以将这些重复出现的对象封装到一起执行任务

 //定义享元抽象Flyweight
public abstract class Rectangle
{
//对象的坐标(属于对象的外蕴部分)
public float PointX { get; set; }
public float PointY { get; set; } //内蕴
public string Color { get; set; }
//边长
public float Width { get; set; }
//设置外蕴
public abstract void SetStart(float x,float y);
} //定义具体享元
public class RedRectangle:Rectangle
{
public RedRectangle()
{
this.Color = "Red";
} public override void SetStart(float x,float y)
{
this.PointX = x;
this.PointY = y;
}
}
public class GreenRectangle : Rectangle
{
public GreenRectangle()
{
this.Color = "Green";
} public override void SetStart(float x,float y)
{
this.PointX = x;this.PointY = y;
}
}
public class BlueRectangle : Rectangle
{
public BlueRectangle()
{
this.Color = "Blue";
} public override void SetStart(float x,float y)
{
this.PointX = x;
this.PointY = y;
}
} //定义一个非共享元
public class UshareRectangle : Rectangle
{
public List<Rectangle> Rectangles { get; set; }
public UshareRectangle()
{ } public override void SetStart(float x, float y)
{
for(int i=;i<Rectangles.Count;i++)
{
Rectangles[].PointX = x+i*;
Rectangles[].PointX = y + i * ;
} }
} //定义享元池
public class FlyweightPool
{
public Hashtable Pool { get; set; } } //定义一个客户端
public static class Client
{
public static void DrawRectangle(Rectangle rectangle,float x,float y)
{
rectangle.SetStart(x, y);
Console.WriteLine("您在({0},{1})处画了一个边长为{2}的{3}正方形"
,rectangle.PointX,rectangle.PointY,rectangle.Width,rectangle.Color);
}
} //测试代码 public class Test
{
private FlyweightPool pool = new FlyweightPool() { Pool = new Hashtable() };//定义一个工厂实例
//在平台上画上2000个随机指定类型的正方形
public void Test1()
{
//画图开始 //在指定的2000个位置画总共2000个正方形
float[][] position = new float[][]; for (int i = ; i < ; i++)
{
position[i] = new float[];
position[i][] = i * ;
position[i][] = i * ;
} Random random = new Random();
for (int i = ; i < ; i++)
{
switch (random.Next())
{
case :
if (pool.Pool["r5"]==null)
{
pool.Pool.Add("r5", new RedRectangle() { Color = "Red", Width = }); } Client.DrawRectangle((Rectangle)pool.Pool["r5"],position[i][],position[i][]);
break;
case :
if (pool.Pool["r10"] == null)
{
pool.Pool.Add("r10", new RedRectangle() { Color = "Red", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["r10"], position[i][], position[i][]);
break;
case :
if (pool.Pool["r15"] == null)
{
pool.Pool.Add("r15", new RedRectangle() { Color = "Red", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["r15"], position[i][], position[i][]);
break;
case :
if (pool.Pool["g5"] == null)
{
pool.Pool.Add("g5", new GreenRectangle() { Color = "Green", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["g5"], position[i][], position[i][]);
break;
case :
if (pool.Pool["g10"] == null)
{
pool.Pool.Add("g10", new GreenRectangle() { Color = "Green", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["g10"], position[i][], position[i][]);
break;
case :
if (pool.Pool["g15"] == null)
{
pool.Pool.Add("g15", new GreenRectangle() { Color = "Green", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["g15"], position[i][], position[i][]);
break;
case :
if (pool.Pool["b5"] == null)
{
pool.Pool.Add("b5", new BlueRectangle() { Color = "Blue", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["b5"], position[i][], position[i][]);
break;
case :
if (pool.Pool["b10"] == null)
{
pool.Pool.Add("b10", new BlueRectangle() { Color = "Blue", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["b10"], position[i][], position[i][]);
break;
case :
if (pool.Pool["b15"] == null)
{
pool.Pool.Add("b15", new BlueRectangle() { Color = "Blue", Width = });
}
Client.DrawRectangle((Rectangle)pool.Pool["b15"], position[i][], position[i][]);
break;
default:
break;
}
} } //重复绘制图形组合
public void Test2()
{
//重复绘制某组合
UshareRectangle urs = new UshareRectangle();
if (pool.Pool["r5"] == null)
{
pool.Pool.Add("r5", new RedRectangle() { Color = "Red", Width = }); }
urs.Rectangles.Add((Rectangle)pool.Pool["r5"]);
if (pool.Pool["r10"] == null)
{
pool.Pool.Add("r10", new RedRectangle() { Color = "Red", Width = }); }
urs.Rectangles.Add((Rectangle)pool.Pool["r10"]);
int x = , y = ;
for (int i = ; i < ; i++)
{ foreach (Rectangle r in urs.Rectangles)
{ Client.DrawRectangle(r, x,y);
x += ;y += ; } }
}
}

面向对象设计模式_享元模式(Flyweight Pattern)解读的更多相关文章

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

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

  2. 设计模式-11享元模式(Flyweight Pattern)

    1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...

  3. 二十四种设计模式:享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...

  4. 【UE4 设计模式】享元模式 Flyweight Pattern

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

  5. 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  6. Java享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...

  7. 设计模式之享元模式(Flyweight)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  8. [设计模式] 11 享元模式 Flyweight

    转 http://blog.csdn.net/wuzhekai1985/article/details/6670298 问题 在面向对象系统的设计何实现中,创建对象是最为常见的操作.这里面就有一个问题 ...

  9. 七个结构模式之享元模式(Flyweight Pattern)

    定义: 运用共享技术对大量细粒度对象的复用,这要求这些对象都很相似,状态变化很小.将这些对象的内部状态和外部状态进行区分,对于内部状态相同的只存储一个对象,而对不同的外部状态则采用不同的操作. 结构图 ...

随机推荐

  1. 522. Longest Uncommon Subsequence II

    Given a list of strings, you need to find the longest uncommon subsequence among them. The longest u ...

  2. 【062有新题】OCP 12c 062出现大量之前没有的新考题-16

    choose one Which users are created and can be used for database and host management of your DBaaS da ...

  3. mongodb postgresql mysql jsonb对比

    mongodb pg mysql jsonb对比 http://erthalion.info/2017/12/21/advanced-json-benchmarks/ 使用禁用jsonb列的压缩 AL ...

  4. javascript数据结构与算法---二叉树(删除节点)

    javascript数据结构与算法---二叉树(删除节点) function Node(data,left,right) { this.data = data; this.left = left; t ...

  5. MVC3学习:利用mvc3+ajax实现删除记录

    首先根据模板生成list视图,上面就会有一个delete的链接,但是模板自带的这种删除,需要另外再打开一个删除页,再进行删除.我们可以利用ajax来改写,实现在当前页删除. 在视图上面,将原来的 @H ...

  6. 链表的反转、合并(不借助额外list数组)

    链表的基本操作:线性表 (单链表.循环链表-python实现) 反转链表: # -*- coding:utf-8 -*- class ListNode: def __init__(self, x): ...

  7. web的脚本安全-CSRF

    CSRF,即Cross-site request forgery,中文一般叫跨站请求伪造. 攻击原理是,用户在A网站(登录,之后打开一个B网站,B网站的脚本(或HTML标签)向A网站发送一个请求,这个 ...

  8. 整理几个 RPC 框架

    gRPChttp://www.grpc.io/https://github.com/grpcMotan支撑微博千亿调用的轻量级RPC框架:Motanhttp://h2ex.com/820WangleW ...

  9. 如何测试你给客户端app开的接口

    这里介绍一款工具用于测试后台给客户端开的接口. 采用http或者https 采用表单或者json格式 这款工具之前是谷歌浏览器的一款插件,后来出现了各个平台的客户端.非常实用. 名叫postman 官 ...

  10. hadoop家族成员

    1.概述 使用hadoop已经有一段时间了,从最开始懵懂到迷茫,再到各种阅读与写作,再到如今各种组合应用,逐渐已经离不开hadoop了,hadoop在大数据行业的成功,加速了它本身的发展,各大社区都能 ...