一,什么是享元模式?

享元模式(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. 微信小程序-wxml-空格

    必须要在<text>标签中 先在标签中写decode="{{true}}"然后 就代表空格了   占一个中文字符

  2. React Native 之SectionList

    接上一篇: /pages/SectionListDemo.js import React, {Fragment,Component} from 'react'; import { SafeAreaVi ...

  3. HDU 6581 Vacation

    Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission( ...

  4. SetwindowText 之线程阻塞

    示意代码: CriticalSection g_Section; CDialog g_Dlg; // 工作线程函数UINT TreadFunc_A(PVOID para){ Sleep(10); g_ ...

  5. 动态DP总结

    动态DP 何为动态DP? 将画风正常的DP加上修改操作. 举个例子? 给你一个长度为\(n\)的数列,从中选出一些数,要求选出的数互不相邻,最大化选出的数的和. 考虑DP,状态设计为\(f[i][1/ ...

  6. JavaScript 查看stack trace

    How can I get a JavaScript stack trace when I throw an exception? Edit 2 (2017): In all modern brows ...

  7. 转:SqlBulkCopy类进行大数据(一万条以上)插入测试

    转自:https://www.cnblogs.com/LenLi/p/3903641.html 结合博主实例,自己测试了一下,把数据改为3万行更明显!! 关于上一篇博客中提到的,在进行批量数据插入数据 ...

  8. Web网站安全

    一.防SQL注入 SQL注入,就是在web提交表单,请求参数的字符串中通过注入SQL命令,提交给服务器,从而让服务器执行注入的恶意的SQL命令的行为,是发生在开发程序的数据库层的安全漏洞. SQl注入 ...

  9. MySQL与MongoDB的不同

    数据存放的巨大不同

  10. C#和.NET获取绝对路径

    c#获取绝对路径:System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log.txt"); .net获取绝 ...