享元模式以共享的方式高效地支持大量的细粒度对象。很多很小的对象,这些对象有很多共同的东西,那就变成一个对象,还有些不同的东西,作为外部的属性,用方法的参数传入

public class FlyweightDemo {
public static void main(String[] args) {
Integer m = 127;
Integer n = 127;
System.out.println(m==n);//结果为true,这就是使用了享元设计模式 Integer a = Integer.valueOf(323);
Integer b = Integer.valueOf(323);
System.out.println(a==b);
} }

在面向对象的程序设计语言看来,一切事务都被描述成对象(Object)。对象拥有状态(属性)和行为(方法),我们将具有相同行为的对象抽象为类(Class),类可以被看作只保留行为的对象模板,类可以在运行时被重新赋予状态数据从而形成了对象。

在运行时,对象占用一定的内存空间用来存储状态数据。如果不作特殊的处理,尽管是由同一个类生成的两个对象,而且这两个对象的的状态数据完 全相同,但在内存中还是会占用两份空间,这样的情况对于程序的功能也许并没有影响,但如果把状态相同的同一类对象在内存中进行合并,必然会大大减少存储空间的浪费。

举一个现实中的例子,某淘宝店经营一款畅销女式皮鞋,每天需要处理大量的订单信息,在订单中需要注明客户购买的皮鞋信息,我们将皮鞋产品抽象出来:

class Shoe{ 

    String color;//颜色
int size;//尺寸
String position;//库存位置 public String getColor() {
return color;
} public void setColor(String color) {
this.color = color;
} public int getSize() {
return size;
} public void setSize(int size) {
this.size = size;
} public String getPosition() {
return position;
} public void setPosition(String position) {
this.position = position;
} }

正如上面的代码所描述,皮鞋分为颜色、尺寸和库存位置三项状态数据。其中颜色和尺寸为皮鞋的自然状态,我们称之为对象内部状态,这些状态数据只与对象本身有关,不随外界环境的改变而发生变化。再来看库存位置,我们将这个状态称为对象的外部状态,外部状态与对象本身无必然关系,外部状态总是因为外界环境的改变而变化,也就是说外部状态是由外界环境来决定的。在本例中,皮鞋今天放在A仓库,明天可能放在B仓库,但无论存放在哪个仓库,同一只皮鞋就是同一只皮鞋,它的颜色和尺寸不会随着存放位置的不同而发生变化。

享元模式的核心思想就是将内部状态相同的对象在存储时进行缓存。也就是说同一颜色同一尺寸的皮鞋,我们在内存中只保留一份实例,在访问对象时,我们访问的其实是对象缓存的版本,而不是每次都重新生成对象。

享元模式仍然允许对象具有外部属性,由于我们访问的始终是对象缓存的版本,所以我们在使用对象前,必须将外部状态重新注入对象。由于享元模式禁止生成新的对象,所以在使用享元模式时,通常伴随着工厂方法的应用。我们来看下面的例子:

class ShoeFactory { 

    Collection<Shoe> shoes = new ArrayList<Shoe>(); 

    Shoe getSheo(String color, int size, String position) {
//首先在缓存中查找对象
for (Shoe shoe : shoes) {
if (shoe.getColor() == color && shoe.getSize() == size) {
//在缓存中命中对象后还原对象的外部属性
shoe.setPosition(position);
return shoe;
}
}
//如果缓存未命中则新建对象并加入缓存
Shoe shoe = new Shoe();
shoe.setColor(color);
shoe.setSize(size);
shoe.setPosition(position);
shoes.add(shoe);
return shoe;
}
}

通过ShoeFactory工厂,我们每次拿到的皮鞋都是缓存的版本,如果缓存中没有我们需要的对象,则新创建对象然后加入缓存中。注意上例中对象的外部属性position是如何注回对象的。www.2cto.com

当我们在自己的业务场景中应用享元模式时,一定要注意分清对象的内部状态和外部状态,享元模式强调缓存的版本只能包含对象的内部状态。

事实上,Java中的String和Integer类都是享元模式的应用的例子,String类内部对所有的字符串对象进行缓存,相同的字符串在内存中只会保留一个版本。类似的,Integer类在内部对小于255的整数也进行了缓存。

享元模式在企业级架构设计中应用的例子比比皆是,现代大型企业级应用中不可或缺的缓存体系也正是在享元模式的基础上逐步完善和发展起来的。

设计模式_享元设计模式(flyweight)的更多相关文章

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

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

  2. 设计模式:享元(FlyWeight)模式

    设计模式:享元(FlyWeight)模式 一.前言     享元(FlyWeight)模式顾名思义,既是轻量级的,原因就是享元,共享元素,这里的元素指的是对象.如何共享对象,那就是在检测对象产生的时候 ...

  3. 面向对象设计模式_享元模式(Flyweight Pattern)解读

    场景:程序需要不断创建大量相似的细粒度对象,会造成严重的内存负载.我们可以选择享元模式解决该问题. 享元抽象:Flyweight 描述享元的抽象结构.它包含内蕴和外蕴部分(别被术语迷惑,这是一种比较深 ...

  4. 设计模式之享元模式(Flyweight)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

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

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

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

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

  7. 设计模式之享元(flyweight)模式

    现在在大力推行节约型社会,“浪费可耻,节俭光荣”.在软件系统中,有时候也会存在资源浪费的情况,例如,在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高.那 ...

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

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

  9. [设计模式] 11 享元模式 Flyweight

    转 http://blog.csdn.net/wuzhekai1985/article/details/6670298 问题 在面向对象系统的设计何实现中,创建对象是最为常见的操作.这里面就有一个问题 ...

随机推荐

  1. [转]NodeBB 环境搭建

    本文转自:https://my.oschina.net/pauli/blog/198405 摘要: Windows 7 下面 NodeBB (https://nodebb.org/)环境搭建      ...

  2. Extjs 项目中常用的小技巧,也许你用得着(4)---Extjs 中的cookie设置

    1.ExtJs设置cookie两种方式 其一:设置cookie如下 saveacct=isForm.getForm().findField('itemselector').getValue(); Ex ...

  3. 根据ip获取地点

    #region 根据ip获取地点 /// 获取Ip归属地 /// </summary> /// <param name="ip">ip</param& ...

  4. 50道sql练习题和答案

    最近两年的工作没有写过多少SQL,感觉水平下降十分严重,网上找了50道练习题学习和复习 原文地址:50道SQL练习题及答案与详细分析 1.0数据表介绍 --1.学生表 Student(SId,Snam ...

  5. Java基础——工厂模式

    通过学习,一句话概括Java工厂模式的特点——通过建立一个工厂来创建对象,不必关心构造对象实例能不能被实例化啊等诸多细节和复杂过程. 工厂模式呢?就像我们从劳动密集型社会转型到技术密集型社会.打个比方 ...

  6. 【Java基础】8、java中的native方法

    native是与C++联合开发的时候用的!java自己开发不用的! 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用.这些函 ...

  7. 从返回的json格式的data数据内随机取得n个

    var arr=[ { "ceo":"张无忌", "conmpany":"阿里妈妈有限公司", "addres ...

  8. RBAC 介绍 (权限)

    RBAC是什么? RBAC是基于角色的访问控制(Role-Based Access Control )在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权 ...

  9. MySQL的事务的处理

    步骤: 1.开启事务 start transaction 当我们开启一个事务的时候,我们对sql的操作都发生在内存中,但是没有真正的反馈到数据库磁盘的文件中! 2.回滚 rollback 回滚,就是恢 ...

  10. .net中反射与IOC容器实现

    反射还是很有用的,比如IOC容器基本上都是通过反射实现的. IOC是什么 IOC:Inversion of Control 控制反转是一种是面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度 ...