享元模式(Flyweight)---结构型
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)---结构型的更多相关文章
- 享元模式 FlyWeight 结构型 设计模式(十五)
享元模式(FlyWeight) “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...
- 设计模式11: Flyweight 享元模式(结构型模式)
Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...
- Java设计模式15:常用设计模式之享元模式(结构型模式)
1. Java之享元模式(Flyweight Pattern) (1)概述: 享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...
- 面向对象设计模式之Flyweight享元模式(结构型)
动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...
- 设计模式 笔记 享元模式 Flyweight
//---------------------------15/04/20---------------------------- //Flyweight 享元模式------对象结构型模式 /* 1 ...
- 设计模式(十)享元模式Flyweight(结构型)
设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...
- 设计模式-11享元模式(Flyweight Pattern)
1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...
- 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 二十四种设计模式:享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
随机推荐
- Hadoop和Spark的Shuffer过程对比解析
Hadoop Shuffer Hadoop 的shuffer主要分为两个阶段:Map.Reduce. Map-Shuffer: 这个阶段发生在map阶段之后,数据写入内存之前,在数据写入内存的过程就已 ...
- 【AtCoder】AGC001
AGC001 A - BBQ Easy 从第\(2n - 1\)个隔一个加一下加到1即可 #include <bits/stdc++.h> #define fi first #define ...
- POJ1631_高深DP
按照那个图形研究比较了一会, 居然发现是最长上升子序列问题, 这个是真的牛逼!! 只不过是题目没有说的那么直白!
- PAT题目AC汇总(待补全)
题目AC汇总 甲级AC PAT A1001 A+B Format (20 分) PAT A1002 A+B for Polynomials(25) PAT A1005 Spell It Right ( ...
- Photon Server 实现注册与登录(五) --- 服务端、客户端完整代码
客户端代码:https://github.com/fotocj007/PhotonDemo_Client 服务端代码:https://github.com/fotocj007/PhotonDemo_s ...
- RabbitMQ快速开始
①:安装rabbitmq所需要的依赖包 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make g ...
- k8s之网络插件flannel及基于Calico的网络策略
1.k8s网络通信 a.容器间通信:同一个pod内的多个容器间的通信,通过lo即可实现; b.pod之间的通信:pod ip <---> pod ip,pod和pod之间不经过任何转换即可 ...
- spring-boot-plusV1.2.3发布,CentOS快速安装环境/构建/部署/启动项目
spring-boot-plusV1.2.3发布,CentOS快速安装环境/构建/部署/启动项目 [V1.2.3-RELEASE] 2019.09.09
- spring——aop详细总结1
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补 ...
- 微信小程序转发事件
和生命周期是同级,在.js文件里面设置 // 分享按钮 onShareAppMessage: function () { return { title: '前端伪大叔', path: "/p ...