享元模式(Flyweight Pattern)

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/409 访问。

享元模式属于结构型模式,它以共享的方式高效的支持大量的细粒度对象。通过复用内存中已存在的对象,降低系统创建对象实例的性能消耗。

享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象,如果找到对象,则直接返回。

角色:

1、抽象享元(Flyweight)

它是所有具体享元类的抽象基类,为其子类规定出需要实现的公共接口;

2、具体享元(Concrete Flyweight)

具体享元类实现了抽象享元类所规定的接口;

3、享元工厂(FlyweightFactoiy)

享元工厂类负责创建和管理享元对象。

示例:

命名空间FlyweightPattern中包含IConnection接口充当抽象享元,Connection类充当具体享元,ConnectionFactory工厂类充当享元工厂。本案例通过使用享元模式来共享数据库连接。

namespace FlyweightPattern
public interface IConnection {

    void Print();

}

IConnection接口,包含一个打印的方法。

public class Connection : IConnection {

    private string _connectionString = null;

    public Connection(string connectionString) {
_connectionString = connectionString;
Thread.Sleep(1000);
Console.WriteLine("It took 1 second(s) to create a connection!");
} public void Print() {
Console.WriteLine($"Database connection is {_connectionString}");
Console.WriteLine("-------------------------------------------------------");
} }

Connection类,定义数据库连接(演示)。

public class ConnectionFactory {

    private Dictionary<string, IConnection> _connections = null;

    private string _connectionString = null;

    public ConnectionFactory() {
_connections = new Dictionary<string, IConnection>();
} public IConnection CreateConnection(string connectionString) {
if (!_connections.ContainsKey(connectionString)) {
Console.WriteLine("Creating a new connection!");
IConnection connection = new Connection(connectionString);
_connections.Add(connectionString, connection);
return connection;
}
else {
Console.WriteLine("Return an exist connection!");
var connection = _connections[connectionString] as IConnection;
return connection;
}
} }

ConnectionFactory类,数据库连接工厂,内部维持对所有连接的引用,CreateConnection方法在发现连接存在时直接返回,如果不存在,则创建一个新的连接并维持进列表。

注:实际开发过程中应该用HashCode来检索数据库连接是否存在。

public class Program {

    private static ConnectionFactory _factory = null;

    private static List<string> _connections = null;

    private static IConnection _connection = null;

    private static void Print(int index) {
if (index > _connections.Count - 1) {
Console.WriteLine("Index Out Of Range Exception!");
return;
}
_connection = _factory.CreateConnection(_connections[index]);
_connection.Print();
} public static void Main(string[] args) {
_connections = new List<string> {
"Server=Aron1;Database=pubs;\n" + "Uid=uid;Pwd=password;",
"Provider=sqloledb;Data Source=Aron1;\n" + "User Id=uid;Password=password;",
"Data Source=192.168.0.1,1433;\n" + "UserID=uid;Password=password;"
}; _factory = new ConnectionFactory(); Print(0);
Print(1);
Print(2);
Print(1);
Print(3); Console.ReadKey();
} }

以上是调用方的代码,以下是这个案例的输出结果:

Creating a new connection!
It took 1 second(s) to create a connection!
Database connection is Server=Aron1;Database=pubs;
Uid=uid;Pwd=password;
-------------------------------------------------------
Creating a new connection!
It took 1 second(s) to create a connection!
Database connection is Provider=sqloledb;Data Source=Aron1;
User Id=uid;Password=password;
-------------------------------------------------------
Creating a new connection!
It took 1 second(s) to create a connection!
Database connection is Data Source=192.168.0.1,1433;
UserID=uid;Password=password;
-------------------------------------------------------
Return an exist connection!
Database connection is Provider=sqloledb;Data Source=Aron1;
User Id=uid;Password=password;
-------------------------------------------------------
Index Out Of Range Exception!

优点:

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/409 访问。

1、降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。

缺点:

1、为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑更复杂,使系统复杂化;

2、享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

使用场景:

1、一个系统中有大量的对象;

2、这些对象耗费大量的内存;

3、这些对象中的状态大部分都可以被外部化;

4、这些对象可以按照内部状态分成很多的组,当把外部对象从对象中剔除时,每一个组都可以仅用一个对象代替;

5、软件系统不依赖这些对象的身份。

C#设计模式之11-享元模式的更多相关文章

  1. Java设计模式之《享元模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6542449.html 享元模式:"享"就是分享之意,指一物被众人共享, ...

  2. C#设计模式学习笔记:(11)享元模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7792973.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲结构型设计模式的第六个模式--享 ...

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

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

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

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

  5. 面向对象设计模式之Flyweight享元模式(结构型)

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

  6. 设计模式学习之享元模式(Flyweight,结构型模式)(20)

    转:http://terrylee.cnblogs.com/archive/2006/03/29/361767.html 摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是 ...

  7. 设计模式学习心得<享元模式 Flyweight>

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

  8. C#设计模式之十一享元模式(Flyweight Pattern)【结构型】

    一.引言 今天我们要讲[结构型]设计模式的第六个模式,该模式是[享元模式],英文名称是:Flyweight Pattern.还是老套路,先从名字上来看看.“享元”是不是可以这样理解,共享“单元”,单元 ...

  9. 11.享元模式(Flyweight Pattern)

    面向对象的代价    面向对象很好地解决了系统抽象性的问题,同时在大多数情况下,也不会损及系统的性能.但是,在某些特殊的应用中下,由于对象的数量太大,采用面向对象会给系统带来难以承受的内存开销.比如: ...

  10. Java设计模式学习记录-享元模式

    前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...

随机推荐

  1. 图解:如何实现最小生成树(Prim算法与Kruskal算法)

    这是图算法的第四篇文章 图解:如何实现最小生成树 文章目录: 1.概念和性质 2.思路探索 3.Kruskal算法 4.Prim算法 5.代码实现 1.概念和性质 今天我们考虑的模型是加权无向图,问题 ...

  2. 事件循环 event loop 究竟是什么

    事件循环 event loop 究竟是什么 一些概念 浏览器运行时是多进程,从任务管理器或者活动监视器上可以验证. 打开新标签页和增加一个插件都会增加一个进程,如下图:  浏览器渲染进程是多线程,包 ...

  3. SpringBoot 接收前端参数的几种方式

    昨天和前端小伙伴在联调是碰到了参数接收不到的错误,我在postman上测试接口是正常的,但是与前端对接时就接受不到参数,请求方式都是get,但是问题就在于json  和 form-data 的区别!这 ...

  4. 技术小菜比入坑 LinkedList,i 了 i 了

    先看再点赞,给自己一点思考的时间,思考过后请毫不犹豫微信搜索[沉默王二],关注这个长发飘飘却靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有技术大佬整理 ...

  5. 详解TCP一:三次握手、四次挥手

    TCP协议同样是运输层的协议,掌握TCP重点要关注这几个问题:顺序问题.丢包问题.连接维护.流量控制.拥塞控制.先解析下TCP报文段结构,相比于UDP要复杂很多. 首先还是两个端口号,对应着具体的应用 ...

  6. Makefile中的目标

    Makefile中的目标 一般目标 目标就是我们需要的最终文件,也是make的最终输出 Makefile的运行机制是:先将目标当成文件,查看文件是否存在,如果存在且是最新,那么直接结束,如果文件不存在 ...

  7. [redis] -- 过期策略篇

    过期处理 定期删除 redis默认是每隔 100ms 就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除 惰性删除 定期删除可能会导致很多过期 key 到了时间并没有被删除掉.所以就 ...

  8. 超简单的jq图片上传

    <label class="file_img" for="file_imgs"> <input class="file_imgs&q ...

  9. 前端学习(六):body标签(四)

    进击のpython ***** 前端学习--body标签 关于前面的都是大部分的标签内容 但是就像衣服一样,除了要有,还要放到适当的位置 我们先来看看一下网页的布局: 就可以看出来,网页都是一块一块的 ...

  10. 跟老刘学运维day02~部署虚拟环境安装Linux系统(1)

    第1章 部署虚拟环境安装Linux系统 所谓“工欲善其事,必先利其器” 1.准备工具 VmwareWorkStation  15.5——虚拟机软件(必需) RedHatEnterpriseLinux ...