1 基础知识

定义:提供了减少对象数量从而改善应用所需的对象结构的方式。特征:运用共享技术有效支持大量细粒度的对象。

本质:分离与共享。

使用场景:

(1)如果一个应用程序使用了大量的细粒度对象,可以使用享元模式来减少对象数量。如果由于使用大量的对象,造成很大的存储开销,可以使用享元模式来减少对象数量,并节约内存。

(2)如果对象的大多数状态都可以转变为外部状态,比如通过计算得到,或是从外部传入等,可以使用享元模式来实现内部状态和外部状态的分离。

(3)如果不考虑对象的外部状态,可以用相对较少的共享对象取代很多组合对象,可以使用享元模式来共享对象,然后组合对象来使用这些共享对象。

优点:大大减少对象的创建,降低系统的内存,使效率提高;减少内存之外其他资源占用。缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱;可能有线程安全问题;维护共享对象,需要额外开销。

注:并不是所有的对象都适合存,因为存的是对象的实例,实例里面存放的主要是对象属性的值。因此,如果被缓存的对象的属性值经常变动那就不适合缓存了,因为真实对象的属性值变化了,那么缓存中的对象也必须要跟着变化,否则缓存中的数据就跟真实对象的数据不同步,可以说是错误的数据了。

因此,需要分离出被缓存对象实例中,哪些数据是不变且重复出现的,哪些数据是经常变化的,真正应该被缓存的数据是那些不变且重复出现的数据,把它们称为对象的内部状态,而那些变化的数据就不缦存了,把它们称为对象的外部状态。这样在实现的时候,把内部状态分离出来共享,称之为享元,通过共享享元对象来减少对内存的占用。把外部状态分离出来,放到外部,让应用在使用的时候进行维护,并在需要的时候传递给享元对象使用。为了控制对内部状态的共享,并且让外部能简单地使用共享数据,提供一个工厂来管理享元,把它称为享元工厂

2 代码示例

场景:假设公司年底要做报告,需要经理多次随机的报告。

员工接口:

public interface Employee {
void report();
}

经理类 Manager :实现员工接口

public class Manager implements Employee {
@Override
public void report() {
System.out.println(reportContent);
}
private String title = "部门经理";
//部门
private String department;
//报告内容
private String reportContent; //set方式注入对象
public void setReportContent(String reportContent) {
this.reportContent = reportContent;
} public Manager(String department) {
this.department = department;
}
}

员工工厂:EmployeeFactory 创建部门经理和报告内容

public class EmployeeFactory {
private static final Map<String,Employee> EMPLOYEE_MAP = new HashMap<String,Employee>(); public static Employee getManager(String department){
//从部门中获取经理
Manager manager = (Manager) EMPLOYEE_MAP.get(department); if(manager == null){
//没有取到经理则创建经理
manager = new Manager(department);
System.out.print("创建部门经理:"+department);
//创建报告
String reportContent = department+"部门汇报:此次报告的主要内容是......";
manager.setReportContent(reportContent);
System.out.println(" 创建报告:"+reportContent);
//放入对象池中,下次便可以直接从其中取出了
EMPLOYEE_MAP.put(department,manager);
}
return manager;
}
}

应用层:

public class Test {
//部门数组
private static final String departments[] = {"RD","QA","PM","BD"}; public static void main(String[] args) {
for(int i=0; i<10; i++){
//随机指定部门
String department = departments[(int)(Math.random() * departments.length)];
Manager manager = (Manager) EmployeeFactory.getManager(department);
manager.report();
}
}
}

外部状态:在经理类中的department属性便是外部状态,是会随机发生变化的。内部状态:经理类中的title属性便是内部状态,无论怎么变都不会发生变化,这里是title在程序中并没有应用到只是作为分析的。

3 相关模式

(1)享元模式与单例模式

这两个模式可以组合使用。通常情况下,享元模式中的享元工厂可以实现成为单例。另外,享元工厂中缓存的享元对象,都是单实例的,可以看成是单例模式的一种变形控制,在享元工厂中来单例享元对象。

(2)享元模式与组合模式

这两个模式可以组合使用。在享元模式中,存在不需要共享的享元实现,这些不需要共享的享元通常是对共享的享元对象的组合对象。也就是说,享元模式通常会和组合模式组合使用,来实现更复杂的对象层次结构。

(3)享元模式与状态模式

这两个模式可以组合使用。可以使用享元模式来共享状态模式中的状态对象。通常在状态模式中,会存在数量很大的、细粒度的状态对象,而且它们基本上都是可以重复使用的,都是用来处理某一个固定的状态的,它们需要的数据通常都是由上下文传入,也就是变化部分都分离出去了,所以可以用享元模式来实现这些状态对象。

(4)享元模式与策略模式

这两个模式可以组合使用。可以使用享元模式来实现策略模式中的策略对象。和状态模式一样,在策略模式中也存在大量细粒度的策略对象,它们需要的数据同样是从上下文传入的,所以可以使用享元模式来实现这些策略对象。

0

享元模式(Flyweight)---结构型的更多相关文章

  1. 享元模式 FlyWeight 结构型 设计模式(十五)

    享元模式(FlyWeight)  “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...

  2. 设计模式11: Flyweight 享元模式(结构型模式)

    Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...

  3. Java设计模式15:常用设计模式之享元模式(结构型模式)

    1. Java之享元模式(Flyweight Pattern) (1)概述:       享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...

  4. 面向对象设计模式之Flyweight享元模式(结构型)

    动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...

  5. 设计模式 笔记 享元模式 Flyweight

    //---------------------------15/04/20---------------------------- //Flyweight 享元模式------对象结构型模式 /* 1 ...

  6. 设计模式(十)享元模式Flyweight(结构型)

    设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...

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

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

  8. 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

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

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

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

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

随机推荐

  1. xss level11

    Level11 (1) (2)毫无头绪,查看PHP源代码发现,是从头文件的referer获取的输入. (3)用Burp抓包,修改头文件如下: (4)再点击Proxy界面的forward,回到浏览器页面 ...

  2. Web文件上传靶场 - 通关笔记

    Web应用程序通常会提供一些上传功能,比如上传头像,图片资源等,只要与资源传输有关的地方就可能存在上传漏洞,上传漏洞归根结底是程序员在对用户文件上传时控制不足或者是处理的缺陷导致的,文件上传漏洞在渗透 ...

  3. dl in image process

    deep learning目前为止无论在分类还是检测上,都是整体的处理,而不会出现像sift这样的局部特征,这个问题或许如果能克服掉,能让检测效果更进一大步.

  4. IP 、127.0.0.1、localhost 三者区别

    一.Ping命令 1.Ping命令,用来检查两台物理机间的TCP/IP网络是否通畅或者网络连接速度,是TCP/IP协议的一部分. 2.PING (Packet Internet Groper),因特网 ...

  5. 4、Wepy-Redux基本使用 参考自https://blog.csdn.net/baidu_32377671/article/details/86708019

    摘抄自https://juejin.im/post/5b067f6ff265da0de02f3887 wepy 框架本身是支持 Redux 的,我们在构建项目的时候,将 是否安装 Redux 选择 y ...

  6. 【shell脚本】字符串和数组的使用

    字符串 可以使用单引号和双引号定义字符串变量但是单引号中不支持变量解析 #! /bin/bashusername="mayuan" str_1="hello ${user ...

  7. VisualStudio2015 安装

    环境:Win10 64位 推荐安装顺序 IIS > Sqlserver > Asp.Net 启动安装程序(出现Logo后需要等待1到2分钟),选择安装路径(注意不要出现中文路径) 勾选需求 ...

  8. 重拾MVC——第二天:Vue学习与即时密码格式验证

    今天是复习MVC的第二天,准备自己写一个后台管理,然后慢慢写大,做全. 个人感觉做 Web 的,前端知识是必备的,所有今天学习了一下 Vue,很多人用这个,我以前没有用过,今天把它补起来. 比较了各个 ...

  9. 【转】js原型链与继承

    原文链接:https://blog.csdn.net/u012468376/article/details/53127929 一.继承的概念 ​ 继承是所有的面向对象的语言最重要的特征之一.大部分的o ...

  10. 11.SSH整合

    由于自己学习的版本比较落后,这里就不总结了 在我这个版本整合的过程中的几点问题: 1.在web.xml的配置过程中: <!-- 如果使用的是load获取数据,在jsp页面申请取得数据时才真正的执 ...