一,什么是享元模式?

享元模式(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. Pytorch详解NLLLoss和CrossEntropyLoss

    是什么? https://www.cnblogs.com/marsggbo/p/10401215.html 具体pytorch怎么运算的 https://blog.csdn.net/qq_222102 ...

  2. python+requests接口自动化框架

    为什么要做接口自动化框架 1.业务与配置的分离 2.数据与程序的分离:数据的变更不影响程序 3.有日志功能,实现无人值守 4.自动发送测试报告 5.不懂编程的测试人员也可以进行测试 正常接口测试的流程 ...

  3. ubuntu16.04 下 C# mono开发环境搭建

    本文转自:https://www.cnblogs.com/2186009311CFF/p/9204031.html 前记 之前我一直不看好C#的前景,因为我认为它只能在windows下运行,不兼容,对 ...

  4. express 和 pm2 建立博客

    前置知识 node.js 相关 服务器相关 在本地参照 express 官网的例子写成后, 上传服务器. 服务器安装 pm2 ,实用 pm2 保护进程. 注意静态文件实用的方法 app.use(exp ...

  5. [BZOJ3199][SDOI2013]escape:半平面交

    分析 好像叫V图什么的. 容易发现,对于每个点,其监视的范围就是这个点与其它所有点的垂直平分线分割平面后的半平面交.由于数据范围很小,所以我们可以直接枚举每个点,使用双端队列求出其监视的范围.若两个点 ...

  6. [BZOJ3236]:[Ahoi2013]作业(莫队+分块)

    题目传送门 题目描述 此时已是凌晨两点,刚刚做了$Codeforces$的小$A$掏出了英语试卷.英语作业其实不算多,一个小时刚好可以做完.然后是一个小时可与做完的数学作业,接下来是分别都是一个小时可 ...

  7. 利用python进行数据分析--pandas入门1

    随书练习,第五章  pandas入门1 # coding: utf-8 # In[1]: from pandas import Series, DataFrame # In[2]: import pa ...

  8. Java 中如何使用clone()方法克隆对象?

    java为什么要 对象克隆: 在程序开发时,有时可能会遇到以下情况:已经存在一个对象A,现在需要一个与A对象完全相同的B 对象,并对B 对象的属性值进行修改,但是A 对象原有的属性值不能改变.这时,如 ...

  9. 一台电脑多个git使用 push 时候出现denied

    http://my.oschina.net/silentboy/blog/220158 当一台电脑上多个git account 的时候, 出现如下问题, $ git push origin maste ...

  10. Java继承和多态-Static关键字

    1. 什么是Static 关键字? Static 能够与变量,方法和类一起使用,称为静态变量,静态方法.如果在一个类中使用static修饰变量或者方法的话,它们可以直接通过类访问,不需要创建一个类的对 ...