享元模式-Flyweight

享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。

本文中的例子如下:

使用享元模式: 小明想看编程技术的书, 就到家里的书架上拿, 如果有就直接看, 没有就去买一本, 回家看. 看完了就放到家里的书架上, 以后再想看了直接就在书架上拿, 不需要再去买同样的这本书了.

不适用享元模式: 小明想看编程技术的书, 就去书店里买一本回家看, 买完后看完了, 书就不知道丢到了哪里去了. 下次想看的时候就找不到了, 还是得去书店里重新买......又得花钱....然而并不长记性, 这回买完了, 看完了, 又丢到一边...下次还是得再买...

Java中实例化一个对象 vs 小明买一本书

在Java中的实例化一个对象, 就像是在买一本书, Java中的对象会随着作用域的退出, 对象会失去引用, 过后就会被垃圾收集器标记, 进行回收.

就相当于小明买完了一本书, 书就丢到了一边, 妈妈收拾屋子就把这本书识别为了垃圾, 就给扔掉了. (被妈妈收走是被动导致的小明每次都重新买一本书, 也有可能小明主动地每次看书都重新买一本, 有钱任性...这种有钱人性的行为在编程语言里就是每次都new一个对象, 而从来不去考虑复用)

Java中把对象放进一个容器里进行维护 vs 小明看完书把书放到书架上 (下面的相同颜色表示相同的行为, 可以互相对照)

在Java中:   使用完一个临时实例化的对象后, 如果以后还想复用, 那么就可以放到一个容器里(对象管理器), 或者更直接的说就比如存到一个HashMap里, 需要用的时候以后从里面直接取出来. 这样HashMap对实例化的对象持有引用, 就不会被GC了, 这样该对象就可以常驻内存, 可以复用了, 不用再实例化同样的一个对象了.

小明:    看完了一本书, 把书放到了书架上, 这样妈妈就知道这本书是小明需要的东西, 就不会把它当成垃圾来处理. 这样这本书就会一直在家里存在, 小明想看的时候, 就到家里的书架拿就可以看了, 不用再重新买同样的一本书了.

BooK接口

书的统一定义.书在本里子中是享元模式里被共享的对象. 应该被放到书架上复用, 而不是买次都重新买.

/**
* 书的统一抽象, 书可以被读
*/
public interface Book {
void read();
}

HeadFirstJavaScript类

/**
* <<HeadFirst JavaScript>>
*/
public class HeadFirstJavaScript implements Book { @Override
public void read() {
System.out.printf("这是一本<<HeadFirst JavaScript>>. (书的编号是:%s)\n", System.identityHashCode(this));
}
}

KotlinInAction类

/**
* <<Kotlin实战>>
*/
public class KotlinInAction implements Book { @Override
public void read() {
System.out.printf("这是一本<<Kotlin实战>>. (书的编号是:%s)\n", System.identityHashCode(this));
}
}

PythonCookBook类

/**
* <<Python编程手册>>
*/
public class PythonCookBook implements Book {
@Override
public void read() {
System.out.printf("这是一本<<Python编程手册>>. (书的编号是:%s)\n", System.identityHashCode(this));
}
}

BookFactory类

import java.util.EnumMap;
import java.util.Map; public class BookFactory { public enum BookType {
PYTHON, JAVASCRIPT, KOTLIN
} private final Map<BookType, Book> shelf; public BookFactory() {
shelf = new EnumMap<>(BookType.class);
} /**
* 想读一本书的话就通过这里来get.
* 如果书架里有, 那么就从书架里拿
* 如果书架里没有, 那么就从书店买一本看, 然后放到书架上
*/
public Book getBook(BookType type) {
Book book = shelf.get(type);
if (book == null) {
switch (type) {
case PYTHON:
book = new PythonCookBook();
shelf.put(type, book);
break;
case JAVASCRIPT:
book = new HeadFirstJavaScript();
shelf.put(type, book);
break;
case KOTLIN:
book = new KotlinInAction();
shelf.put(type, book);
break;
default:
break;
}
}
return book;
}
}

Main

运行/模拟场景

public class Main {

    public static void main(String[] args) {
BookFactory bookFactory = new BookFactory(); bookFactory.getBook(BookFactory.BookType.JAVASCRIPT).read();
bookFactory.getBook(BookFactory.BookType.JAVASCRIPT).read(); bookFactory.getBook(BookFactory.BookType.PYTHON).read();
bookFactory.getBook(BookFactory.BookType.PYTHON).read(); bookFactory.getBook(BookFactory.BookType.KOTLIN).read();
bookFactory.getBook(BookFactory.BookType.KOTLIN).read();
bookFactory.getBook(BookFactory.BookType.KOTLIN).read(); // 书的编号一样, 说明书复用了, 而不是每次都买一个新的
}
}

结果如下 :

如果对象不是共享的, 也就是非享元模式, 那么<<Kotlin实战>>的三次的书编号都会是不一样的, 因为每次看这本书, 都是新买的, 最终会导致买三次<<Kotlin实战>>这本书, 同样的书买三次多浪费啊.  而本文的例子使用了享元模式, 拿了三次<<Kotlin实战>>这本书, 每次编号都是1360875712, 说明从头到尾都是同一本书, 没有造成浪费.

享元模式-Flyweight(Java实现)的更多相关文章

  1. Java享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...

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

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

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

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

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

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

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

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

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

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

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

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

  8. 《JAVA设计模式》之享元模式(Flyweight)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述享元(Flyweight)模式的: Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是 ...

  9. 七个结构模式之享元模式(Flyweight Pattern)

    定义: 运用共享技术对大量细粒度对象的复用,这要求这些对象都很相似,状态变化很小.将这些对象的内部状态和外部状态进行区分,对于内部状态相同的只存储一个对象,而对不同的外部状态则采用不同的操作. 结构图 ...

随机推荐

  1. Linux(Manjaro) - Docker - MySQL 安装配置

    Linux(Manjaro) - Docker - MySQL 安装配置 拉取mysql镜像 # 使用网易的 MySQL 镜像地址 docker pull hub.c.163.com/library/ ...

  2. PLSQL Developer图形化界面新建用户并授权并导入脚本

    最近用了PLSQL Developer第三方的软件.记录一下实现新建用户并授权并导入脚本的功能. 第一步.切换sys用户(如果此处方法已经掌握,直接切换sys即可,就不用看这一步了) 首先检查当前登录 ...

  3. servlet中 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver异常

    解决方法:将mysql-connector-java-xxx-bin.jar包,复制到项目下WebContent/WEB-INF/lib目录下,刷新重启tomcat运行即可.

  4. 28 Python初学(事件驱动模型)

    参考文章地址:http://www.cnblogs.com/yuanchenqi/articles/5722574.html 两个步骤: recvfrom 系统调用 : 拷贝数据 从kernel到数据 ...

  5. 如何将div高度填满剩余高度

    下列代码中navbar高度为30px,content高度需要填满浏览器的剩余高度 <div id="body">     <div id="navbar ...

  6. PHP+Mysql 实现数据库增删改查

    PHP和Mysql可以对数据库进行简单的增删改查,本文介绍了新闻列表的后台管理. Mysql数据库创建 创建一个新闻列表的数据库: 1. 查询数据库 1.1. 创建文件dbconfig.php,保存常 ...

  7. 有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?

    事件起因 最初是网友的一个提问,来自于我的知识星球社区: 说实话,不得不佩服这个网友的眼力,这么小的细节都能发现.不过这也正是 FineUI 一直前进的动力,来自社区的监督和促进. 从截图上看,貌似圆 ...

  8. VS2019 实用设置

    本文记录了 VS2019 预览版使用过程中的一些设置,这些设置也同样适用于 VS2017,我们可以根据个人的实际情况进行修改. 滚动条(Scroll Bar) 将滚动条设置为 map mode 后,则 ...

  9. python操作Excel、openpyxl 之图表,折线图、饼图、柱状图等

    一.准备 需要模块: from openpyxl.workbook import Workbook from openpyxl.chart import Series,LineChart, Refer ...

  10. laravel 开启定时任务需要操作

    1.在xshell 中 crontab -e //编辑任务crontab -l //查看执行中的任务列表 2.在打开的任务中: /home/wwwroot/default 换为自己项目的根路径 vag ...