C#设计模式:享元模式(Flyweight Pattern)
一,什么是享元模式?
享元模式(Flyweight Pattern):采用共享技术来避免大量拥有相同内容对象的开销,主要用于减少创建对象的数量,以减少内存占用和提高性能
1,根本的思路就是对象的重用
2,根本的实现逻辑就是简单工厂+静态缓存
二,如下代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static FlyWeightPattern.FlyweightFactory; namespace FlyWeightPattern
{ ///享元模式(FlyWeight):采用共享技术来避免大量拥有相同内容对象的开销
// 当我们项目中创建很多对象,而且这些对象存在许多相同模块,这时,我们可以将这些相同的模块提取出来采用享元模式生成单一对象,再使用这个对象与之前的诸多对象进行配合使用,这样无疑会节省很多空间。
class Program
{
static void Main(string[] args)
{
////相同对象执行时,这样减少创建对象的开销,
//for (int i = 0; i < 5; i++)
//{
// Chinese ch = FlyweightFactory.GetChineseObject("中文");
// ch.Say();
//} for (int i = ; i < ; i++)
{
Task.Run(()=> {
People ch = FlyweightFactory.GetChineseObject(LanguageType.Chinese);
ch.Say();
});
}
for (int i = ; i < ; i++)
{
Task.Run(() => {
People usa = FlyweightFactory.GetChineseObject(LanguageType.USA);
usa.Say();
});
}
}
}
public abstract class People
{
public abstract void Say();
}
public class Chinese : People
{
public Chinese()
{
Console.WriteLine($"{this.GetType().Name}被创建了");
}
public override void Say()
{
Console.WriteLine("中国人说:你好");
}
}
public class USA : People
{
public USA()
{ Console.WriteLine($"{this.GetType().Name}被创建了");
}
public override void Say()
{
Console.WriteLine("USA:Hello");
}
}
}
FlyweightFactory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace FlyWeightPattern
{
/// <summary>
/// 1,根本的思路就是对象的重用
/// 2,根本的实现逻辑就是简单工厂+静态缓存
/// </summary>
public class FlyweightFactory
{
private static Dictionary<LanguageType, People> dic = new Dictionary<LanguageType, People>(); //定义字典来保存不同的变量,相同的则取出
public static object dic_Lock = new object();
public static People GetChineseObject(LanguageType Language)
{
People people = null;
if (!dic.ContainsKey(Language)) //先判空,多并发不需要排序
{
lock (dic_Lock) ///线程锁,当多线程并发时,如果没有lock或造成dic2已经存在KEY的错误
{
if (!dic.ContainsKey(Language)) //定义字典来保存不同的变量,相同的则取出
{
switch (Language)
{
case LanguageType.Chinese:
people = new Chinese();
break;
case LanguageType.USA:
people = new USA();
break;
}
dic.Add(Language, people); //我们将新创建的对象存储到缓存中
}
}
}
return dic[Language];
}
public enum LanguageType
{
Chinese,
USA,
}
}
}
在多并发时的享元模式如果没有加锁的判断会出下一下的问题,字典的KEY冲突

三,我们解析下亨元模式代码设计思路
1,围绕减少相同对象的创建设计使我们代码设计的核心
2,判定对象是否存在,如果存在则取出,否则就创建,这样避免对象的重复,我们通过Key来实现唯一性
四,string的享元模式详解
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace StringDemo
{
class Program
{
static void Main(string[] args)
{
string str = "May";
string str1 = "May";
///object.ReferenceEquals这个方法是判断内存地址是否相等
///根据string本身的定义,string在赋值的时候,会主动开辟一块不一样的内存空间,但是这里输出True
///原因:string 是使用享元模式,在赋值的时候会去堆中查找看是否存在May,如果存在str1就指向该堆中的内存地址,这是CLR内存分配机制决定的,字符串的享元是全局的,不是局部的
Console.Write(object.ReferenceEquals(str,str1)); str = "June";
///按引用类型来理解,str1输出的应该是June,但是结果这里输出的是May,值不变
///原因:根据string本身的定义,string在赋值的时候,字符串的不可变性, str = "June"等于重新new一个string,会主动开辟一块不一样的内存空间
Console.WriteLine(str1); string str3 = string.Format("M{0}","ay");
///这里输出false,因为str3在初始化中还不知道是不是May字符串,所以开辟了一块新的内存,这里不是享元模式了
Console.WriteLine(object.ReferenceEquals(str,str3)); string str4 = "M";
string str5 =str4+ "ay";
///这里输出false
Console.WriteLine(object.ReferenceEquals(str,str5)); string str6 = "M" + "ay";
///这里输出True
///原因:"M" + "ay"在编译过程中,编译器自动编译成"May", 所以输出的是True
Console.WriteLine(object.ReferenceEquals(str, str6)); Console.ReadKey();
}
}
}
1,String 使用了享元模式初始化,比如我们定义两个string 都赋值是may,按道理来说string都是重新开辟内存空间的,
2,我们用判断内存地址去判断两个值得内存地址是一样的,原因是string 初始化时去判断堆中是否有may 了,
3,享元模式的原理,字符串享元是全局的,不是局部的,在一个进程中,只有一个堆,所以指向同一个地址的字符串是一样的
C#设计模式:享元模式(Flyweight Pattern)的更多相关文章
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- 设计模式-11享元模式(Flyweight Pattern)
1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...
- 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 二十四种设计模式:享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...
- Java享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...
- 【UE4 设计模式】享元模式 Flyweight Pattern
概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...
- 设计模式-享元模式(FlyWeight)
一.概念 享元模式是对象的结构模式,它以共享的方式高效的支持大量的细粒度对象,减少对象的数量,并达到节约内存的目的. 享元对象能够做到共享的关键,主要是区分了内部状态和外部状态,内部状态是对象是在建立 ...
- 七个结构模式之享元模式(Flyweight Pattern)
定义: 运用共享技术对大量细粒度对象的复用,这要求这些对象都很相似,状态变化很小.将这些对象的内部状态和外部状态进行区分,对于内部状态相同的只存储一个对象,而对不同的外部状态则采用不同的操作. 结构图 ...
- 享元模式(Flyweight Pattern)
定义: 采用一个共享来避免大量拥有相同内容对象的开销.这种开销中最常见.直观的就是内存的损耗.享元模式以共享的方式高效的支持大量的细粒度对象. 享元的英文是flyweight,是一个来自体育方面的专业 ...
- 设计模式--享元模式Flyweight(结构型)
一.享元模式 在一个系统中如果有多个相同的对象,这些对象有部分状态是可以共享的,我们运用共享技术就能有效地支持大量细粒度的对象. 二.例子 举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子. ...
随机推荐
- js的字符串是数字时过长的时候会被截断
JavaScript能表示并进行精确算术运算的整数范围为:正负2的53次方,也即从最小值-9007199254740992到最大值+9007199254740992之间的范围:对于超过这个范围的整数, ...
- Java——常用类(File)
[File] <1>java.io.File类代表系统文件名(路径和文件名). ----注意:这里代表的只是文件名,而不是物理上的文件(硬盘上的数据),通过该类无法读 ...
- CG-CTF | I wanna play CTF
这题跟bugku上的come_game超级像,于是菜狗决定研究一下,先鸣谢一下好友the fool,菜狗一直卡在开始界面哇,谢谢大佬给的第一关的数据 这是过到关卡1的数据,经过一系列的尝试得到结论: ...
- 2.Vue子组件给父组件通信
子组件给父组件通信 如果子组件想要改变数据呢?这在vue中是不允许的,因为vue只允许单向数据传递,这时候我们可以通过触发事件来通知父组件改变数据,从而达到改变子组件数据的目的 子组件: <te ...
- Atcoder arc079 D Decrease (Contestant ver.) (逆推)
D - Decrease (Contestant ver.) Time limit : 2sec / Memory limit : 256MB Score : 600 points Problem S ...
- hypermesh中怎么设置支反力(反作用力)
Analysis page >> Control cards >> Global output request 勾选 SPCF 和 GPFORCE .
- DAY 6 TEST
test T1 样例输入 样例输出 答案选择u,v作为关键点 暴力的话k^2枚举跑最短路,寻找最小值就行了 50pts 考虑优化枚举量 因为答案的两个点是不同的点,所以编号的二进制表示中至少一位不同 ...
- Sails.js中文文档,Sails中文文档
Sails.js中文文档 http://sailsdoc.swift.ren/ Sails.js是一个Web框架,可以于轻松构建自定义,企业级Node.js Apps.它在设计上类似于像Ruby ...
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_04 数据结构_5_数据结构_红黑树
生活中的树和计算机中的树.计算机的树是倒着的
- JMeter Gui – TestElement约定(转自约会言行的博客,链接:http://blog.csdn.net/yue530tomtom/article/details/77649872?locationNum=4&fps=1)
在编写任何JMeter组件时,必须注意某些特定的约定——如果JMeter环境中正确地运行JMeter组件,那么它将会运行.本部分描述了组件的GUI部分必须满足的约定. JMeter中的GUI代码严格地 ...