享元模式(Flyweight)

简介: 享元模式(Flyweight)

什么是享元模式 ?

运用共享技术有效地支持大量细粒度的对象。

我觉得它很像我们平常说的容器,只不过这个容器是用哈希表来存储的数据,通过键值对的形式,先把key和value值添加到哈希表里面,放入这个享元池里面,客户端通过提供的key值来获取value对象。这样的好处是什么呢?在享元池里面的key值不会重复,相同key值和value值的对象只会实例化一次,这样的话就不会产生重复的对象,避免资源的浪费。


4b7b7c710b43c42bc448dc593df03b1d.png


有什么优点?

减少对象的创建,降低内存的占用,提高效率



有什么缺点?

使得系统更加复杂,为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。



什么时候使用呢?

一个应用程序使用了大量的对象;


这些对象大多数可以外部状态时。



代码展示

场景:小菜其他私营业主做网站,需要做多个网站,但要求不太一样,有的人希望是新闻发布形式的,有人希望是博客形式的,也有还是原来的产品图片加说明形式的,而且他们都希望在费用上能大大降低。可是每个网站租用一个空间,费用上减低是不太可能的。怎么办呢?我们就可以使用享元模式。



①、享元模式

Flyweight类

abstract class Flyweight           //抽象类
{
    public abstract void Operation(int extrinsicstate);   //抽象方法
}

ConcreteFlyweight类

class ConcreteFlyweight : Flyweight            //具体享元
    {
        public ConcreteFlyweight() { }        //创建此类无参构造方法
        public override void Operation(int extrinsicstate)  //重写Operation方法,并接收外部传来的参数
        {
            Console.WriteLine("具体Flyweight:" + extrinsicstate);   //在控制台输出结果
        }
}

UnsharedConcreteFlyweight类

class UnsharedConcreteFlyweight : Flyweight    //不需要共享的Fleweight子类
{
    public override void Operation(int extrinsicstate)   //重写抽象方法,并接受外部传来的参数
    {
        Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);  //在控制台输出结果
    }
}

FlyweightFactory类

class FlyweightFactory
{
        private Hashtable flyweights = new Hashtable();    //创建一个哈希表
        public FlyweightFactory()                          //创建此类的构造方法
        {
            //初始化工厂时,先生成三个实例
            flyweights.Add("X", new ConcreteFlyweight());  //往哈希表添加一个键值对X
            flyweights.Add("Y", new ConcreteFlyweight());  //往哈希表添加一个键值对Y  
            flyweights.Add("Z", new ConcreteFlyweight());  //往哈希表添加一个键值对Z
        }
        public Flyweight Getflyweight(string key)
        {
            return ((Flyweight)flyweights[key]);     //根据客户端请求,获得已生成的实例
        }
}

客户端类

int extrinsicstate = 22;    //外部代码状态
FlyweightFactory f = new FlyweightFactory();   //实例化享元工厂
Flyweight fx = f.Getflyweight("X");   //创建一个网站fx对象,调用享元工厂的Getflyweight方法,将值赋给fx对象
fx.Operation(--extrinsicstate);       //调用网站的Operation对象,extrinsicstate-1
Flyweight fy = f.Getflyweight("Y");   //创建一个网站fy对象,调用享元工厂的Getflyweight方法,将值赋给fy对象
fy.Operation(--extrinsicstate);       //调用网站的Operation对象,extrinsicstate-1
Flyweight fz = f.Getflyweight("Z");   //创建一个网站fz对象,调用享元工厂的Getflyweight方法,将值赋给fz对象
fz.Operation(--extrinsicstate);       //调用网站的Operation对象,extrinsicstate-1
Flyweight uf = new UnsharedConcreteFlyweight();   //创建一个不共享的flyweight子类
uf.Operation(--extrinsicstate);      //调用网站的Operation对象,extrinsicstate-1
Console.ReadKey();


154ac9fc87944ac9ce156896103babb5.png


目录
相关文章
|
存储 NoSQL Redis
容器部署日志分析平台ELK7.10.1(Elasisearch+Filebeat+Redis+Logstash+Kibana)
容器部署日志分析平台ELK7.10.1(Elasisearch+Filebeat+Redis+Logstash+Kibana)
948 0
|
Java 数据库
SpringBoot定时将数据库表生成Excel表格
SpringBoot定时将数据库表生成Excel表格
191 0
|
敏捷开发 监控 容灾
阿里巴巴DevOps实践指南(二十二)| 发布策略
DevOps 追求更短的迭代周期、更高频的发布。但发布的次数越多,引入故障的可能性就越大。更多的故障将会降低服务的可用性,进而影响到客户体验。所以,为了保证服务质量,守好发布这个最后一道关,阿里逐步发展出了适应 DevOps 要求的发布策略。
阿里巴巴DevOps实践指南(二十二)| 发布策略
|
10月前
|
前端开发 API UED
React 路由守卫 Guarded Routes
【10月更文挑战第26天】本文介绍了 React 中的路由守卫(Guarded Routes),使用 `react-router-dom` 实现权限验证、登录验证和数据预加载等场景。通过创建 `AuthContext` 管理认证状态,实现 `PrivateRoute` 组件进行路由保护,并在 `App.js` 中使用。文章还讨论了常见问题和易错点,提供了处理异步操作的示例,帮助开发者提升应用的安全性和用户体验。
352 1
|
9月前
|
SQL 机器学习/深度学习 编解码
R中单细胞RNA-seq分析教程 (4)
R中单细胞RNA-seq分析教程 (4)
R中单细胞RNA-seq分析教程 (4)
|
11月前
|
Java
【编程基础知识】《Java 复用魔法:组合、继承与代理的奇妙之旅》
本文《Java 复用魔法:组合、继承与代理的奇妙之旅》深入解析了 Java 中的三种主要代码复用技术——组合、继承和代理,通过实例和图表详细说明了它们的概念、作用及应用场景,旨在帮助读者提升 Java 编程技能。
116 0
|
自然语言处理
|
JSON API 数据库
Django的web框架Django Rest_Framework精讲(一)
Django的web框架Django Rest_Framework精讲(一)
481 1
|
移动开发 JavaScript 前端开发
HTML5作业(二)-----扑克牌拖放小游戏
该实验旨在理解元素拖放、CSS定位和DOM操作,任务是创建一个扑克牌拖放游戏。用户需将A框内13张随机扑克牌(背面朝上)按顺序拖至B框,最多存5张。当B框内形成顺子时游戏结束,显示拖动次数。实验提供HTML结构及部分JavaScript代码,包括创建和乱序扑克牌、处理拖放事件等。
260 0
|
存储 安全 Java
CopyOnWriteArrayList底层原理全面解析【建议收藏】
CopyOnWriteArrayList是Java中的一个线程安全的集合类,是ArrayList线程安全版本,主要通过Copy-On-Write(写时复制,简称COW)机制来保证线程安全。 Copy-On-Write机制核心思想:向一个数组中添加数据时,不直接操作原始数组,而是拷贝原始数组生成一份原始数组副本,将需要添加的数据添加到原始数组副本中,操作完成后再用原始数组副本直接替换原始数组,从而保证多个线程同时操作原始数组时的线程安全。