Head First设计模式<二>:享元模式
1 介绍
享元模式主要用于减少对象的数量,以减少内存占用性和提高性能。这种类型的设计模式属于结构型模型,他提供了减少对象数量从而改善应用所需的对象结构的方式。(概念ps:来自百度)
意图:享元模式就是用共享技术有效的支持大量细粒度对象的复用。减少对象的重复创建,实现对象的多个复用功能。
两个概念:内部状态,外部状态。这个是我们学习享元模式必须要知道的重要点之一。
内部状态:我们在享元对象内部定义的成员,不会因为外部环境的改变而改变,内部状态只做对象功能的定义。内部状态是被共享的状态。
外部状态:随着外部环境的改变而改变,我们需要使用共享状态来实现不同的功能效果,这个不被共享的状态就是外部状态。
关于使用:
1: 系统中有大量的对象。
2:这些对象消耗大量内存。
3:这些对象的状态大部分可以外部化,内部状态可以实现共享。
2 模式结构:
不多哔哔了,上个结构图给大家凑合看一下,我们就开始撸代码。
3 设计实现:
步骤一:创建一个鸭子的共享功能接口:
1 package com.alibaba.Flyweight; 2 3 /** 4 * 鸭子群 5 * 6 * @author Mr.Tk 7 * @date 2019/3/09 14:30 8 */ 9 public interface Ducks { 10 11 /** 12 * 游泳 13 */ 14 void swim(); 15 }
步骤二:再来一个鸭子的共享内部状态
1 package com.alibaba.Flyweight.impl; 2 3 import com.alibaba.Flyweight.Ducks; 4 5 /** 6 * 鸭子实例 7 * 8 * @author Mr.Tk 9 * @date 2019/3/09 14:33 10 */ 11 public class Duck implements Ducks { 12 13 //鸭子品种 14 private String name; 15 16 //飞行技能 17 private String fly; 18 19 //叫声 20 private String quack; 21 22 //鸭子颜色 23 private String color; 24 25 public Duck(String name) { 26 this.name = name; 27 } 28 29 public void setColor(String color) { 30 this.color = color; 31 } 32 33 public void setFly(String fly) { 34 this.fly = fly; 35 } 36 37 public void setQuack(String quack) { 38 this.quack = quack; 39 } 40 41 @Override 42 public void swim() { 43 System.out.println("门前大桥下游过一只鸭。。。" 44 + "color:" + color + " name:" + name + " fly:" + fly + " quack:" + quack); 45 } 46 }
步骤三:享元工厂和享元池的创建
package com.alibaba.Flyweight; import com.alibaba.Flyweight.impl.Duck; import java.util.HashMap; import java.util.Map; /** * 鸭子的享元工厂 * * @author Mr.Tk * @date 2019/3/09 14:47 */ public class DuckFactory { /** * 工厂内部维护的享元池 */ private static final Map<String, Duck> map = new HashMap<>(); /** * 工厂可以选择自己制造鸭子的方法入参方式,我这里为了方便观看选择参数入参, 实际使用中可以选择对象入参避免参数过多代码可读性降低。 * * @return Duck */ public static Duck getDuck(String name) { Duck duck = (Duck)map.get(name); if (null == duck) { duck = new Duck(name); map.put(name, duck); System.out.println("鸭子品种 --> " + name); } return duck; } }
步骤四:模拟一下实现
1 package com.alibaba.strategy; 2 3 import com.alibaba.Flyweight.DuckFactory; 4 import com.alibaba.Flyweight.impl.Duck; 5 6 public class Test { 7 8 private static final String names[] = {"Red鸭子", "yellow鸭子", "木头鸭子", "99鸭"}; 9 10 public static void main(String[] args) { 11 //颜色 12 String colors[] = {"红色", "绿色", "黄色", "麻辣色"}; 13 //飞行 14 String flys[] = {"展翅高飞", "不会飞", "躺着飞"}; 15 //叫声 16 String quacks[] = {"嗷嗷叫", "吱吱叫", "不会叫"}; 17 18 /************************ 享元模式 ***********************************/ 19 for (int i = 0; i < 10; i++) { 20 Duck duck = DuckFactory.getDuck(names[(int)(Math.random() * names.length)]); 21 duck.setColor(colors[(int)(Math.random() * colors.length)]); 22 duck.setFly(flys[(int)(Math.random() * flys.length)]); 23 duck.setQuack(quacks[(int)(Math.random() * quacks.length)]); 24 duck.swim(); 25 } 26 } 27 }
看下运行结果:
4 总结
4.1 优点
1 :享元模式能够极大的减少系统中对象的个数。
2:享元模式由于使用的外部状态,外部状态相对独立,不会影响到内部状态,所以享元对象能够在不同的环境被共享使用。
4.2 缺点
1:由于享元模式需要区分外部状态和内部状态,使得程序再一定程度上被复杂化。
2:为了使对象可以被共享,享元模式需要将享元对象的状态外部化,外部状态的增加使得程序读取运行的时间变长。
矛盾说:我从来不梦想,我只是在努力认识现实。
戏剧家洪深说:我的梦想是明年吃苦的能力比今年更强。
鲁迅说:人生最大的痛苦是梦醒了无路可走。
苏格拉底说:人类的幸福和欢乐在于奋斗,而最有价值的是为理想而奋斗。