一,什么是享元模式?

享元模式(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. 048:ORM模型基本的增删改查操作

    ORM对数据库的增删改查基本操作: 创建模型如下: 基本的增删改查如下:

  2. 【bzoj4552】【Tjoi2016&Heoi2016】【NOIP2016模拟7.12】排序

    题目 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次 ...

  3. JDK1.8 LinkedList双向链表源码

    序言 LinkedList是一个双向链表 也就是说list中的每个元素,在存储自身值之外,还 额外存储了其前一个和后一个元素的地址,所以也就可以很方便地根据当前元素获取到其前后的元素 链表的尾部元素的 ...

  4. [CF1188B]Count Pairs 题解

    前言 这道题目是道好题. 第一次div-2进前100,我太弱了. 题解 公式推导 我们观察这个式子. \[(a_i+a_j)(a_i^2+a_j^2)\equiv k \mod p\] 感觉少了点什么 ...

  5. WEB编程 入门简单 进阶难

    其实不论是WEB还是其他什么编程,都是这个道理,至于为什么,我贴几段代码,大家感受下. JS 计算今天是星期几 入门级 // 计算系统当前是星期几 var str =""; var ...

  6. [BZOJ1478&1488&1815][SGU282]Isomorphism:Polya定理

    分析 三倍经验题,本文以[BZOJ1478][SGU282]Isomorphism为例展开叙述,主体思路与另外两题大(wan)致(quan)相(yi)同(zhi). 这可能是博主目前写过最长也是最认真 ...

  7. MySQL高可用方案 MHA之一MHA安装

    MHA0.58安装 MHA(Master High Availability)由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点).管理节点mha4mysql-manager ...

  8. docker 提高效率 network-bridging 桥接

    安装的时间顺序 bit3 192.168.107.128 wredis 192.168.107.129 wmysql 192.168.107.130 wslave 192.168.107.131 w ...

  9. leetcode 720. 词典中最长的单词

    /* 1.hashtable 把每个字符串都放到hashtable中 a.排序 长度不同,长的放在前面,长度相同,字典序小的放在前面 b.不排序 遍历数组,对于每个字符串判断它的所有前缀是否都在has ...

  10. Vue知识整理2:Vue生命周期方法

    在vue执行过程中,可以分为beforeCreate.created.BeforeMount.mounted  .BeforeUpdate.updated 等常用的方法,如下图所示. 除此之外,通过查 ...