设计模式_享元设计模式(flyweight)
享元模式以共享的方式高效地支持大量的细粒度对象。很多很小的对象,这些对象有很多共同的东西,那就变成一个对象,还有些不同的东西,作为外部的属性,用方法的参数传入
- 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)的更多相关文章
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- 设计模式:享元(FlyWeight)模式
设计模式:享元(FlyWeight)模式 一.前言 享元(FlyWeight)模式顾名思义,既是轻量级的,原因就是享元,共享元素,这里的元素指的是对象.如何共享对象,那就是在检测对象产生的时候 ...
- 面向对象设计模式_享元模式(Flyweight Pattern)解读
场景:程序需要不断创建大量相似的细粒度对象,会造成严重的内存负载.我们可以选择享元模式解决该问题. 享元抽象:Flyweight 描述享元的抽象结构.它包含内蕴和外蕴部分(别被术语迷惑,这是一种比较深 ...
- 设计模式之享元模式(Flyweight)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 设计模式-11享元模式(Flyweight Pattern)
1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...
- 二十四种设计模式:享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...
- 设计模式之享元(flyweight)模式
现在在大力推行节约型社会,“浪费可耻,节俭光荣”.在软件系统中,有时候也会存在资源浪费的情况,例如,在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高.那 ...
- 【UE4 设计模式】享元模式 Flyweight Pattern
概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...
- [设计模式] 11 享元模式 Flyweight
转 http://blog.csdn.net/wuzhekai1985/article/details/6670298 问题 在面向对象系统的设计何实现中,创建对象是最为常见的操作.这里面就有一个问题 ...
随机推荐
- 如何让win2008服务器显示中文无乱码
使用Windows Server 2008 R2 IIS搭建FTP服务器时,客户端登录FTP后中文文件夹显示为乱码,应在“控制面板”-“区域和语言”中查看“当前系统区域设置”的情况. 应确保“非Uni ...
- 【ibatis】IBatis的SQL批量操作
1.Ibatis批量添加(传入class的list即可) <insert id="Add" resultMap="Select" parameterCla ...
- 【Java并发编程】3、DelayQueue应用场景,多考生考试
该场景来自于:http://www.cnblogs.com/sunzhenchao/p/3515085.html. 模拟一个考试的日子,考试时间为120分钟,30分钟后才可交卷,当时间到了,或学生都交 ...
- 使用 RabbitMQ 实现异步调用
目录 引言 启动 RabbitMQ 服务器 运行 rabbitmq 容器 RabbitMQ 控制台 Exchange 和 Queue 开发服务端和客户端 开发服务端 开发客户端 Java Bean 类 ...
- Ubuntu 18.04 安装 Docker-ce(就是Docker社区版本)
一步都不用改,跟着走就行 1.更换国内软件源,推荐中国科技大学的源,稳定速度快(可选) sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak ...
- 数据定义语句(DDL语句)
建立表 create table 表名( 字段名1 类型, 字段名2 类型, ........ 字段名n 类型): 类型有: char(n) 是一个类型,叫定长字符串,数据不够就补空格 v ...
- linux系统编程:read,write与lseek的综合应用
这个实例根据命令行参数进行相应的读学操作: 用法: usage:./io file {r<length>|R<length>|w<string>|s<offs ...
- HDU1281(KB10-D 二分图最大匹配)
棋盘游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- onkeyup小练习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Oracle中Merge的使用
MERGE INTO products p USING product_changes pc ON (p.product_id = pc.product_id) WHEN MATCHED THEN - ...