一,什么是享元模式?

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

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

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

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

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

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

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

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

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

  5. Java享元模式(Flyweight Pattern)

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

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

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

  7. 设计模式-享元模式(FlyWeight)

    一.概念 享元模式是对象的结构模式,它以共享的方式高效的支持大量的细粒度对象,减少对象的数量,并达到节约内存的目的. 享元对象能够做到共享的关键,主要是区分了内部状态和外部状态,内部状态是对象是在建立 ...

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

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

  9. 享元模式(Flyweight Pattern)

    定义: 采用一个共享来避免大量拥有相同内容对象的开销.这种开销中最常见.直观的就是内存的损耗.享元模式以共享的方式高效的支持大量的细粒度对象. 享元的英文是flyweight,是一个来自体育方面的专业 ...

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

    一.享元模式 在一个系统中如果有多个相同的对象,这些对象有部分状态是可以共享的,我们运用共享技术就能有效地支持大量细粒度的对象. 二.例子 举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子. ...

随机推荐

  1. 【GDOI 2016 Day1】第二题 最长公共子串

    分析 首先,可以发现,区间是可以合并滴.把区间按左端点排序,对于两个区间[l1,r1].[l2,r2],当l1<=l2 and r1>=l2,那么,将它们合成一个新的区间[l1,r2].当 ...

  2. CSS——相对定位、绝对定位、固定定位

    相对定位: position:relative 当元素被设置相对定位或是绝对定位后,将自动产生层叠,他们的层叠级别自然的高于文本流,除非设置其z-index值为负值. 并且我们发现当相对定位元素进行位 ...

  3. flask入门,Hello World!

    flask这个框架简单易用,去年2018的使用份额已经快接近django了.入门首选,没有太多的要求. 接下来,写个Hello World吧 1.新手入门,如果你是在windows下使用的,需要先安装 ...

  4. 文本跟随鼠标并且显示x轴和y轴位置

    一.文本跟随鼠标并且显示x轴和y轴位置 代码如下: window.onload=function(){ var mydiv = document.createElement("div&quo ...

  5. HDU 1276 士兵队列训练问题(模拟)

    原题代号:HDU 1276 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1276 题目原题: 士兵队列训练问题 Time Limit: 2000/10 ...

  6. Swift equality

    最后更新: 2017-07-23 在程序开发中,我们时常需要来判断两个对象是否相等.在编程思想中,两个对象相等指的是在内存中的地址相同,也就是两个指针指向同一个地址.但是在日常理解中,只要两个对象的内 ...

  7. instanceof用来判断啥?

    java中的instanceof运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例.

  8. Linux shell - 重命名文件和文件夹(mv)

    linux下重命名文件或文件夹的命令mv既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a目录移动到/b下,并重命名为c mv /a /b/c

  9. mui.ajax中文乱码

    估计这是个bug: //mui 的 ajax 中文乱码 var url = 'http://api.juheapi.com/japi/toh?key=1f26c107d8864bdfb98202bc3 ...

  10. 爱好-超级IP:超级IP

    ylbtech-爱好-超级IP:超级IP  IP,是Intellectual Property的缩写,字面粗译为“知识产权”,特指具有长期生命力和商业价值的跨媒介内容运营.一个具有可开发价值的真正的I ...