画笔盒的智慧(享元模式)
画笔盒的智慧
我们都知道,小孩儿画画都有一个画笔盒,这是一件很普通的事情,但是这其中蕴含着大智慧。
今天我们用一个设计模式来阐述一下这其中的智慧。
一、初识享元模式
享元模式(Flyweight Pattern) 主要的作用是减少创建对象的数量。
大家都晓得,对象比较占内存(跟你对象似的,衣柜全是她占了),享元模式就是通过减少创建对象来减少内存和提高性能的。
享元模式属于结构型模式,他提供了减少对象数量从而改善引用所需对象结构的方式。
说白了,就是想方设法减少对象,其实我理解享元模式的时候就会想到"单例模式",我的理解是能单例的都单例了,实在不能单例了才会享元。
就是一个对象能解决的事情就不要找俩了,你想生个俩小宝宝,你总不能一胎找一个对象,二胎找一个对象吧。你也太不是人了。
我们项目中如果有大量的相似对象 或者 类似缓冲池的场景 的时候 我们可以考虑这种设计模式。
比如Java的String、数据库连接池 都是使用的这种设计模式,可能当时他们不是为了使用这种设计模式才那样设计但是那样设计的结果是符合这种设计模式。
在工作中我们也是一样,没有地方找理论的时候,那就去做,做完了你就得出理论了。勇敢牛牛向前冲。
二、小二上图
我们用画五颜六色的线条来做示例
这里注意了,各种颜色的线条创建都是由一个工厂控制的,这也很容易理解,不然没法统一管理和存储,跟单例一样,总得有一个地方存储。
三、写一写
我们的线条定义了起始坐标和终止坐标。想画某个颜色的线条时,先看有没有这个颜色的线条对象,以的话直接用,没有的话先创建,再用。
Shape
package flyweight;/*** @author 木子的昼夜编程* 图形接口,约束画图行为*/
public interface Shape {void draw();
}
Line
package flyweight;/*** @author 木子的昼夜编程* 具体线条类 画五颜六色线条*/
public class Line implements Shape{// 起始坐标 终止坐标int startX,startY,endX,endY;// 颜色String color;public Line(String color){this.color = color;}/*** 画线*/@Overridepublic void draw() {String str = "起始坐标:{%s,%s},终止坐标:{%s,%s},颜色:%s";String res = String.format(str, startX, startY, endX, endY, color);System.out.println(res);}public int getStartX() {return startX;}public void setStartX(int startX) {this.startX = startX;}public int getStartY() {return startY;}public void setStartY(int startY) {this.startY = startY;}public int getEndX() {return endX;}public void setEndX(int endX) {this.endX = endX;}public int getEndY() {return endY;}public void setEndY(int endY) {this.endY = endY;}
}
ShapeFactory
````jpackage flyweight;import java.util.HashMap;/*** @author 木子的昼夜编程* 负责存储各种颜色线条 和 生产线条*/
public class ShapeFactory {private static HashMap<String, Shape> lineMap = new HashMap<>();// 根据不同颜色获取Linepublic static Shape getLine(String color){// 如果不存在就创建颜色对应的lineif (!lineMap.containsKey(color)) {System.out.println("创建线条:"+color);lineMap.put(color, new Line(color));}// 返回Linereturn lineMap.get(color);}}
FlyWeightPatternDemo
package flyweight;/*** @author 木子的昼夜编程*/
public class FlyWeightPatternDemo {public static void main(String[] args) {// 红色线条画画Line line01 = (Line) ShapeFactory.getLine("红色");line01.setStartX(0);line01.setStartY(0);line01.setEndX(1);line01.setEndY(1);line01.draw();// 红色线条画画Line line02 = (Line) ShapeFactory.getLine("红色");line02.setStartX(2);line02.setStartY(3);line02.setEndX(4);line02.setEndY(5);line02.draw();System.out.println(line01 == line02);// 蓝色线条画画Line line03 = (Line) ShapeFactory.getLine("蓝色");line03.setStartX(12);line03.setStartY(34);line03.setEndX(45);line03.setEndY(56);line03.draw();}
}
四、唠一唠
通过示例我们可以看到,红色线条第一次是创建,第二次就是直接从缓存获取了,第二次与第一次使用的是一个对象。
问题1: 正是因为我们获取的是一个对象,所以我们使用的时候一定要注意线程安全问题,如果多个线程同时使用红色线条画图肯定是会出问题的,所以理解我们尽可能使用只读的对象,比如上边的起始终止坐标,我们不要设置到Line属性上,我们当参数传给draw方法
问题2:ShapeFactory 创建shape的方法是有问题的,没有保证线程安全,可以参考单例DCL 自行优化
与我们的画笔盒一样,把所有颜色的画笔都存储在画笔盒,我们想画什么颜色图形就找对应颜色的画笔,而不是每次去买一个画笔(创建一个对象),画笔用完了我们就放回画笔盒,而不是扔了(创建对象用完销毁)。
以后遇到学美术的,给他讲讲享元模式吧。
画笔盒的智慧(享元模式)相关推荐
- Java设计模式之享元模式(UML类图分析+代码详解)
大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...
- 享元模式:如果让你开发英雄联盟的兵线,你会怎么设计?
享元模式 运用共享技术来有效地支持大量细粒度对象的复用. 这个设计模式在 GOF 的书中是用 flyweight 这个词来定义这种模式的,然后翻译成中文就叫 享元 了,讲真挺不自在,首先这个词是一个自 ...
- 设计模式之享元模式(Flyweight)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 【设计模式】享元模式
上周代码评审,看到同事使用了"享元模式".想起自己也不懂,着手学习之. 参考的优秀的文章: Java的享元模式 这篇博文为学习之理解.感悟,如理解不真确,请慷慨指出. 本文只讨论单 ...
- Python设计模式-享元模式
Python设计模式-享元模式 基于Python3.5.2,代码如下 #coding:utf-8class Coffee:name = ""price = 0def __init_ ...
- 设计模式之享元模式、例子分析
1. 定义 享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象 按我的理解来说,享元,就是共享单元,重复运用,这个模式的核心是复用代码,按不同需要,创建并共用一个实例(不同需要是共 ...
- 13Flyweight(享元)模式
技术交流QQ群:1027579432,欢迎你的加入! 1.Flyweight(享元)模式动机 在软件系统采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价--主要指 ...
- 享元模式 Flyweight Pattern
享元模式的定义为:采用一个共享来避免大量拥有相同内容对象的开销. 这种开销中最常见.直观的就是内存的损耗.享元模式以共享的方式高效地支持大量的细粒度对象. 在名字和定义中都体现了共享这个核心概念,那么 ...
- JAVA 设计模式 享元模式
用途 享元模式 (Flyweight) 运用共享技术有效地支持大量细粒度的对象. 享元模式是一种结构型模式. 结构 图-享元模式结构图 Flyweight : 它是所有具体享元类的超类或接口,通过这个 ...
最新文章
- windows下的linux开发环境Mingw与Cygwin
- 一个小清新的知识管理和问题讨论平台
- dokuwiki 的管理和使用
- 【bzoj3160】万径人踪灭
- HDU 1159.Common Subsequence【动态规划DP】
- 把ASP应用中的Session传递给asp.net应用
- mysqlbinlog日志一天产生太多脚本
- 2017.2.18 loli测试
- 国庆档首日票房破2亿 长津湖票房占比过半
- NET Micro FrameworkのTimerクラス攻略
- scala 协变和逆变_Scala方差:协变,不变和逆变
- Google 编程之夏:海量优质项目,丰厚报酬,你竟然还不知道?
- excel甘特图模板_不做规范!收数就是个灾难!Excel收集数据套路了解一下
- C语言位运算的取反(~)真实原理解析
- 利用google地图获取位置经纬度坐标
- transforms常用函数简介
- 2D游戏引擎开发入门(二)
- C#远程启动、终止进程
- oracle48108,​记一次oracle连接数暴涨hang分析经验
- 实验吧WEB CTF 猫抓老鼠 全网最简单易懂的解题方法
热门文章
- 怎么抓取股票交易接口?
- Python安装教程(2022最新)
- springboot幼儿园幼儿基本信息管理系统设计与实现 毕业设计-附源码201126
- C语言实现单向循环链表
- 算法中的P问题、NP问题、NP完全问题和NP难问题梳理
- 解决Element type “web-app“ must be followed by either attribute specifications, “>“ or “/>“.报错问题
- c印记(一):面向对象
- java基于微信小程序音乐播放器分享系统 uniapp 小程序
- ENVI自带地物波谱库文件说明和查看(以ENVI5.3为例)
- FPGA NCO+FIRip核的使用及仿真(加法)(quartusii 13.1+modelsimse 10.5)