设计模式——享元模式
来源:互联网 发布:景观设计需要哪些软件 编辑:程序博客网 时间:2024/05/16 14:42
Author:云都小生
继承提高代码的复用性,享元模式提高对象的复用性。
推荐!史上最全设计模式导学目录
前述
我不知道大家有没有打过什么枪战游戏,那里面的子弹,都是一样的。若每一个子弹都是相同的对象,只不过每个子弹的位置不一样,那我们是不是得不断的new出一大堆的对象嘞?
换个案例,围棋,黑棋和白棋其实都是一模一样的,只是每一个棋子的位置不一样,那我们是不是得new好多个对象。那样肯定会造成内存浪费,而享元模式,就可以用来解决这种问题。
无论是在C语言还是在Java中,创建一个字符串“云都小生”,如果还创建一个字符串变量也是“云都小生”,那么都会指向同一个对象,这个也是为了避免内存浪费。
享元模式概述
当一个软件系统在运行时产生的对象数量过多,又有很多相同具有许多相同的、类似的对象时,我们就可以考虑用享元模式去尝试着优化。
在享元模式中有一个存储共享实力对象的地方,被称为——享元池。
在享元模式中还有两个概念非常重要,一个是内部状态,另一个是外部状态。
内部状态就是在享元对象内部,并且不会随着环境改变而改变的。你看像围棋中的棋子,除了颜色和位置,其他的就算放到其他地方也不会变。
外部状态就是会随着环境改变而改变的,就像上面所说的位置一样。
角色分析
抽象享元类:一个接口或抽象类,声明了具体享元类公共的方法。这些方法向外提供享元对象的内部数据,也提供了方法来设置外部数据。
在围棋游戏中,抽象享元类相当于语义中的“棋子”。
具体享元类:实现了抽象享元类,为内部状态提供了存储空间,每一个具体享元类都有一个唯一的享元对象。
在围棋游戏中,抽象享元类相当于语义中的“黑棋”“白棋”,无论黑棋和白棋有多少个,它们都有共享的特性——例如颜色、大小。
非共享具体享元类:不能被共享的子类可以设计成非共享具体享元类,非共享具体享元类也实现了抽象享元类。
在整个框架中,可能会有一些特殊且没有办法共享的对象,我们可以设计成非共享具体类。例如说飞行器中,确实各方的飞机棋子差不多,有一些特性可以共享。但是!有一个骰子,这个对象是不能共享的。
享元工厂类:享元模式引入了工厂类,享元工厂类用于创建并管理享元对象。它定义了一个集合(通常是一个键值对集合hash)),用来存储享元对象。
享元工厂类,在用户请求一个享元对象的时候,就会在享元池中找到相应的享元对象。如果找不到,就创建一个新的享元对象并返回。
代码示范1(内部状态)
//抽象享元类:棋子抽象类abstract class Chessman { public abstract String getColor(); public void display() { System.out.println("棋子颜色:" + this.getColor()); } public void refsize() { System.out.println("棋子大小:2cm x 2cm"); }}//具体享元类:黑色棋子public class BlackChessman extends Chessman{ public String getColor() { return "黑色"; }}//具体享元类:白色棋子public class WhiteChessman extends Chessman{ public String getColor() { return "白色"; }}//享元工厂类:棋子创建、存储、管理(包含享元池)import java.util.Hashtable;public class ChessmanFactory { private static ChessmanFactory factory = new ChessmanFactory(); private static Hashtable ht; //享元池 private ChessmanFactory() { ht = new Hashtable(); Chessman black,white; black = new BlackChessman(); ht.put("black", black); white = new WhiteChessman(); ht.put("white", white); } //返回享元工厂类的唯一实例 public static ChessmanFactory getInstance() { return factory; } //通过key来获取存储在Hashtable中的享元对象 public static Chessman getChessman(String color) { return (Chessman)ht.get(color); } }//客户端类public class Client { public static void main(String[] args) { Chessman black1,black2; Chessman white1,white2; //获取享元工厂对象 ChessmanFactory factory = ChessmanFactory.getInstance(); black1 = factory.getChessman("black"); black2 = factory.getChessman("black"); System.out.println("判断两颗黑子是否相同:" + (black1==black2)); white1 = factory.getChessman("white"); white2 = factory.getChessman("white"); System.out.println("判断两颗黑子是否相同:" + (white1==white2)); }}
其实我重点比较关注享元工厂类,它实现了享元池,对享元对象进行创建、存储、管理。通过客户端类的测试,我们也更清楚了,享元模式确保了对象的唯一性,还实现了对象的共享。在很大程度上节省了内存。
但是在上面这个案例中,我们只有共享的具体享元类,也就是颜色、大小这些特性是可以共享。但是像位置,这些特性是没办法共享的,也就是外部状态,这个怎么做?
代码示范2(外部状态)
//位置类(外部状态)public class Position { private int x; private int y; public Position(int x,int y) { this.x = x; this.y = y; } public int getX() { return this.x; } public void setX(int x) { this.x = x; } public int getY() { return this.y; } public void setY(int y) { this.y = y; }}//棋子抽象类(增加显示位置)abstract class Chessman { public abstract String getColor(); public void display(Position position) { System.out.println("棋子颜色:" + this.getColor()); System.out.println("位置是:" + position.getX() + "," + position.getY()); } public void refsize() { System.out.println("棋子大小:2cm x 2cm"); }}//客户端类public class Client { public static void main(String[] args) { Chessman black1,black2; Chessman white1,white2; //获取享元工厂对象 ChessmanFactory factory = ChessmanFactory.getInstance(); black1 = factory.getChessman("black"); black2 = factory.getChessman("black"); System.out.println("判断两颗黑子是否相同:" + (black1==black2)); white1 = factory.getChessman("white"); white2 = factory.getChessman("white"); System.out.println("判断两颗黑子是否相同:" + (white1==white2)); black1.display(new Position(1,2)); black2.display(new Position(3,4)); white1.display(new Position(2,5)); white2.display(new Position(2,4)); }}
这样就共享了同一个对象,但是外部状态——显示位置不一样。
2017/12/11 15:37:59 @Author:云都小生
- 设计模式——享元模式
- 设计模式——享元模式
- 【设计模式】——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式——享元模式
- 设计模式—FlyWeight享元模式
- 随机选择第i小元素
- CHM电子书反编器BAT版
- okhttp post请求
- 值5只被赋值给变量B
- 一句话简单总结李航统计学习法各算法
- 设计模式——享元模式
- 【线性模型】对数几率回归(LR)
- 文本格式转换为数字:汪琪玩Excel第十五招
- 双12砍价就要简单粗暴:来试试你的刀法如何!一刀一个价
- JAVA的四种访问修饰符
- 更新github项目上的代码
- Android--广播发送者及广播接收者
- 迷茫
- Python函数篇(3)-内置函数、文件处理