我们来coding享元模式,享元模式的重点就是共享,网站需要各个管理者上传报告,如果这些报告已经生成过了,我们就没有必要再去new一个了,我们来通过这场景来体现一下享元模式,这里面我们也会结合工厂模式,首先我们创建一个包,结构型,这里创建一个享元的包,flyweight,flyweight英文的愿意呢,是指轻量级的,如果用英英字典来解析的话,最轻量级的类,那在中文翻译成享元模式,还是非常贴切的,那我们首先创建一个员工的接口

首先看这三个类,下面的应用层先不看,这个关系还是非常简单的,重点在这个工厂中,EMPLOYEE_MAP,然后他两是组合关系,EmployeeFactory的getManager的返回值,是Employee,然后他来创建对应的Manager,Manager又实现Employee,那整体来说,享元模式理解起来也非常容易,那我们也强调了,在使用享元模式的时候,我们一定要关注线程安全问题,例如说现在这个Test,那在getManager的时候,这里面使用的就是HashMap,并不是线程安全的,而且我们这里面也没有加同步锁,那对于作报告这种简单的场景,如果我们多线程过来的时候,其实并没有必要关注他的线程安全问题,我们说的线程安全问题,其实也是要享元模式一定要保证他的线程安全,这个还是要根据实际的应用场景进行取舍,那现在我们来思考一下,对于这个部门经理,department这个属性,现在是声明在外部的,Manager的department属性,它是在外部来声明的,并且Manager的department的状态依赖于外部传入的一个参数,所以我们可以认为他是外部状态,因为我传入不同的department,所获得的这个Manager,他里面的department的属性是不一样的,对于Manager这个实体,我们就可以认为这个状态department这个状态,是外部状态,那怎么理解内部状态,很简单,我们写一个private String title,直接赋值部门经理,这个时候我们外部怎么传department,或者reportContent,Manager的title是不变的,他不随外部的department的状态变化而变化,他的title永远是部门经理,非常容易理解,之所以把title放到这里面讲,而不是之前讲呢,是因为前面我们也有说,大家在coding的时候呢,就开始思考,然后在这里面我们再强调一下,并且产生对比,这样你们对外部状态和内部状态肯定会理解的,那这种例子非常多,假设我们现在要用程序,画圆形,而这个圆形的半径,如果我们是固定好的,那他就是内部状态,如果这个圆形的半径需要我们在应用层,客户端代码来传入的话,那么他就是外部状态,那我们再思考一个问题,如果这个圆形还要有颜色呢,希望你们能继续思考一下,非常简单,那享元模式就讲到这里,我们看一下享元模式在一些源码的应用
package com.learn.design.pattern.structural.flyweight;/*** 这个接口我们有一个方法report* 部门的Manager当然也是员工* 他实现员工这个接口之后呢* 也就要实现report接口* 我们再创建一个类* Manager* * @author Leon.Sun**/
public interface Employee {/*** 做报告* * */void report();
}
package com.learn.design.pattern.structural.flyweight;/*** 实现Employee* 然后实现他的接口* 既然是部分的Manager* 他的属性就是所在的部门* * * @author Leon.Sun**/
public class Manager implements Employee {/*** 那在report的时候就比较简单了* 因为报告的内容我已经拿到了* 所以我们直接输出* reportContent* 开始做报告* 那这两个映射类OK了* 我们还要创建一个类呢* 是工厂* 通过Employee的工厂呢* 来获取对应的Manager* 对应的Employee* 那我们这里只关注Manager* 因为现在只让Manager做报告* 我们Employee不需要做报告* * */@Overridepublic void report() {System.out.println(reportContent);}private String title = "部门经理";/*** 部门*/private String department;/*** 那在做报告的时候* 需要有内容的* 所以他还持有一个报告的内容* reportContent* 这么两个属性* 那这个Manager在new的时候* 我肯定是应该知道* 他在哪个部门的* *    */private String reportContent;/*** 那对于reportContent* 我们可以在外部重置reportContent* 所以我们加一个reportContent的set方法* * * @param reportContent*/public void setReportContent(String reportContent) {this.reportContent = reportContent;}/*** 这里加一个构造器* 这个构造器只传一个department就可以了* * * @param department*/public Manager(String department) {this.department = department;}
}
package com.learn.design.pattern.structural.flyweight;import java.util.HashMap;
import java.util.Map;/*** EmployeeFactory这个类是工厂类* 你们肯定是相当熟悉了* 之前有系统的学习过* 工厂相关的模式* 而且在单例模式中* 也学过容器单例* 所以这个类如何实现* 相信大部分是心里有数的* 那我们这一节就当一个复习* 非常简单* 轻松加愉快的来学习享元模式* * * * @author Leon.Sun**/
public class EmployeeFactory {/*** 首先我们来创建一个容器* final的Map* key是String* value是Employee* 这个就叫EMPLOYEE_MAP* 因为我们使用static和final* IDEA会自动提示使用大写的命名* 直接new一个HashMap* 然后泛型写上* 我们都是用原生的JDK来做* 现在把Mape的包导入一下* * */private static final Map<String,Employee> EMPLOYEE_MAP = new HashMap<String,Employee>();/*** 我们再写一个方法* 返回者肯定是这个类getManager* 就是需要从EMPLOYEE_MAP中获取对应的Manager* Manager也是Employee* 接下来想要哪个经理来做报告* 这个部门我们就要交给外部来传* 以后我们在使用的时候* 你们就要回想一下* 我们之前有讲过内部状态和外部状态* 这个时候大家就可以跟着思考一下* 这个时候我们传入一个入参* department* * * * @param department* @return*/public static Employee getManager(String department){/*** 然后获取一个Manager* 直接从这里面获得一个Manager* 赋值成什么呢* 肯定是从Map里面直接取* get的key肯定就是部门* 这里面需要我们强转* * 首先从Map里面获取一个Manager* * */Manager manager = (Manager) EMPLOYEE_MAP.get(department);/*** 这个时候做一些空判断* 如果manager是空的话* * 如果没有获取到* 就new一个放进去* 如果我们还想让同一部门的经理来做报告的话* 那我们直接从对象池中取出来* 就不需要new了* 接下来我们来写一下主函数* Test测试类* * */if(manager == null){/*** 那我们就new一个manager出来* 把department传进去* * manager现在有部门了* 那还需要让他来创建报告* * */manager = new Manager(department);System.out.print("创建部门经理:"+department);/*** 然后把报告内容统一一下* * */String reportContent = department+"部门汇报:此次报告的主要内容是......";/*** 所以我们直接在这里面manager.setReportContent* 首先是部门名称加上部门汇报* 谁来汇报* 此处的报告内容是* 开始做报告了* 那我们把这个顺序改一下* 设置完报告呢* 就输出一个创建报告* 然后reportContent放到这里边* 这样当这个经理第一次来做报告的时候* 首先我们这个系统要创建这个经理* 然后再创建这个报告* 都创建好之后* 放到这个对象池里边* 下次做报告直接从池里拿* 不再走这个new的过程* 我们现在回到Test里边* * */manager.setReportContent(reportContent);System.out.println(" 创建报告:"+reportContent);/*** 然后往EMPLOYEE_MAP中put* 把这个department和manager放进去* * */EMPLOYEE_MAP.put(department,manager);}/*** 直接return manager* 非常简单* 那捋一下逻辑* * */return manager;}
}
package com.learn.design.pattern.structural.flyweight;/*** 也就是应用层的代码* * * @author Leon.Sun**/
public class Test {/*** 首先我们声明一个部门的常量* final的* 我们直接用一个String的数组就行* departments的一个数组* 这里面我们想象一下* 我们有研发部门* 还有呢QA部门* 还有PM部门* 还有BD部门* 其他的部门我们就不写了* * */private static final String departments[] = {"RD","QA","PM","BD"};/*** 我们写一个主函数* * * @param args*/public static void main(String[] args) {/*** 从这个部门随机的取* 有一个for循环* * */for(int i=0; i<10; i++){/*** 首先我们有一个department* 这里面有一个随机数从departments数组里随机的取* 也就是说用这个数组的索引取随机数* 这样这个部门也就随机了* 打个比方* 今天副总经理让研发的Manager做报告* 过了几天呢* 总经理又来说* 研发的经理过来* 大概年底的时间* 部门的Manager经常要做报告* 各种报告层出不穷* 所以这里还真的特别适合响应模式* 我们接着写* 从departments里面直接取一个* 取一个下角标* Math.random()这个方法* 让他乘上departments的length* 就OK了* 进行类型的转换* 把它转换成int* 这样就从里面随机的获取元素* 来获取这个部门的名称* 然后Manager* * * */String department = departments[(int)(Math.random() * departments.length)];/*** 来获取这个Manager* * EmployeeFactory.getManager* 把department传进去* 这里面按照提示强转一下* 那在Manager第一次做报告的时候* 报告还没有准备好* 所以第一次的时候* 他需要new一个报告出来* 那以后就不需要new了* 就直接拿过来* 开始做汇报* 所以我们来到getManager这里边* * * */Manager manager = (Manager) EmployeeFactory.getManager(department);/*** 做报告* * manager点report方法* 那么现在来run一下* 来看一下结果是什么样子的* 我们看一下* 这里是10次的循环* 首先把QA的经理叫过来了* 让他做报告* 他赶快创建一个报告* 主要是......* 而第二次的时候* 又让他做一次报告* 他呢不需要再创建了* 我这里有现成的* 对于我们这个对象池我们这个经理也在* 他的报告也在* 那第三次叫BD的经理来做报告了* 然后连着让他做两次* 又叫QA的部门来做报告了* 他还是直接拿过来做报告* 然后叫PM的部门来做报告* 然后叫RD的部门来做报告* 那这些都是一样的* 创建过程也是一样的* 我们接着回来* 因为这里的代码业务逻辑非常简单* 就不领着一起来debug了* 而且我们在之前学习容器单例的时候* 这个知识点都有学过* 而且这里面的逻辑清晰而简单* 那我们来解析一下他的类图* * * */manager.report();}
//        Integer a = Integer.valueOf(100);
//        Integer b = 100;
//
//        Integer c = Integer.valueOf(1000);
//        Integer d = 1000;
//
//        System.out.println("a==b:"+(a==b));
//
//        System.out.println("c==d:"+(c==d));}
}

享元设计模式coding相关推荐

  1. Java设计模式(十八):享元设计模式

    1. 应用场景 当我们项目中创建很多对象,而且这些对象存在许多相同模块,这时,我们可以将这些相同的模块提取出来采用享元模式生成单一对象,再使用这个对象与之前的诸多对象进行配合使用,这样无疑会节省很多空 ...

  2. Integer注意_享元设计模式

    public class IntegerNote{ public static void main(String[] args){   Integer d1=100;   Integer d2=100 ...

  3. 结构设计模式 - Flyweight设计模式(享元设计模式)

    结构设计模式 - Flyweight设计模式 今天我们将研究Flyweight 设计模式,Flyweight设计模式又被称为 享元设计模式 . 目录[ 隐藏 ] 1 Flyweight设计模式 1.1 ...

  4. 黑马程序员--高新技术--静态导入,基本数据类型拆箱与装箱,享元设计模式

    静态导入 import语句可以导入一个类或某个包中的所有类 import static语句导入一个类中的某个静态方法或所有静态方法或静态变量 使用静态导入可以使被导入类的静态变量和静态方法在当前类直接 ...

  5. Java中的享元设计模式,涨姿势了!

    首先来看一段代码: public class ShareTest {public static void main(String[] args) {Integer a = 127;Integer b ...

  6. java设计模式之享元设计模式

    一.构成 单纯享元模式 抽象享元角色:定义了公共的接口,所有的具体享元角色需要实现的接口,那些需要外蕴状态的操作可以通过方法的参数传入. 具体享元角色:实现抽线享元角色所规定的公共接口,如果有内蕴状态 ...

  7. 设计模式之——享元设计模式

    享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式.享元模式尝试 ...

  8. 自动装箱与拆箱引发的享元设计模式

    2019独角兽企业重金招聘Python工程师标准>>> /*** 自动装箱与拆箱*/ public class Autoboxing {public static void main ...

  9. 设计模式—享元设计模式

    目录 1.概述 2.结构 3.案例实现 4.优缺点和使用场景 5.JDK源码解析 1.概述 定义 运用共享技术来有效地支持大量细粒度对象的复用.它通过共享已经存在的对象来大幅度减少需要创建的对象数量. ...

最新文章

  1. JAVA入门到精通-第73讲-学生管理系统5-dao.sqlhelper
  2. linux Fedora搭建hadoop平台总结
  3. python 12 socket 编程
  4. PAT甲级1094 The Largest Generation:[C++题解]邻接表存树、每层节点数量、vector模拟bfs层序遍历、bfs另类实现
  5. gen_caltab生成标定文件
  6. 什么是闪电网络节点_为什么以及如何计划闪电谈话
  7. DateTimeFormatter,时间格式化与解析日期或时间
  8. Linux目录下有剩余空间,但无法写入数据
  9. 群晖做网页服务器_群晖NAS服务器管理后台的登入教程
  10. 如何查看oracle隐含参数,Oracle如何查看隐含参数
  11. Safari 兼容问题累积
  12. Solr分组聚合查询之Facet
  13. java连连看项目汇报_java连连看小项目 - osc_x4wlt5vu的个人空间 - OSCHINA - 中文开源技术交流社区...
  14. 中国哪座城市“最会玩”?“这里是宇宙电竞中心”
  15. 电商设计师(美工)必备|模板素材网站!
  16. 电脑没声音,喇叭上一个叉,显示无法找到输入输出设备(录制,耳机等等)
  17. 再度公开少林内修心法 易筋经和洗髓经 欢迎转载 让全人类共享学习 过得更健康
  18. 史上最全 | HBase 知识体系吐血总结
  19. 2022-2028全球外墙建筑保温材料市场现状及未来发展趋势
  20. vue3父子组件通信

热门文章

  1. CentOS服务器iptables配置
  2. Pocket PC 2003 SE设备仿真器网络设置
  3. linux 根目录突然增大
  4. 通过Chrome模拟和调试网速慢的情况来限制一些P2P视频网站上传速度占满的情况...
  5. Hive:表1inner join表2结果group by优化
  6. 薛老师软考高项学员:2016年4月6日作业
  7. 通达OA 新旧两种数据库连接方式
  8. JAVA NIO是什么(zz)
  9. 铁钉的blog地址 http://nails.blog.51cto.com
  10. 打印控件---引用网友推荐