“怎么回事,竟然出现了OutOfMemory的错误。鱼哥,来帮我看看啊。”“有跟踪错误原因么?是内存泄露么?”“不是内存泄露啊,具体原因不知道啊。对了,有说新对象申请不到内存空间。”“这个原因么,我曾写过一篇博文:叫OutOfMemory简单分析。不过你的明显是因为代码问题,产生对象太多,导致内存被耗尽,正好一会有堂课,讲的正好能解决你的问题。”(嘿嘿,轮到我享元模式出场了~)
我,享元模式乃是池技术中的重要实现方式,具体定义如下:Use sharing to support large numbers of fine-grained objects efficiently.翻译过来就是说使用共享对象可以有效的支持大量的细粒度的对象。由定义可知两个要求:细粒度的对象和共享对象。前面那个人出现的问题就是内存溢出,就是因为分配了太多的对象导致了内存溢出,当然还会有损程序的性能。那么如何解决呢,没错就是我所提供的共享技术。在这之前先了解一下对象的外部状态以及内部状态。
细粒度对象不可避免会使对象数量多且性质相近,那我们就将这些对象分为两部分,也就是外部状态和内部状态。下面解释一下内部状态与外部状态:
我的类图如下:
类图中每个类行驶的功能以及详细的介绍了,我也就不废话了。
优点:
缺点:
俗话说,没有银弹,但是却有通用的实现的代码, 我水平那么高,自然会用通用的代码来实现我的模式~我的模式我做主,首先是抽象享元角色:
1 public abstract class Flyweight{ 2 //内部状态 3 private String intrinsic; 4 //外部状态 5 protected final String Extrinsic; 6 //要求享元角色必须接受外部状态 7 public Flyweight(String extr){ 8 this.Extrinsic = extr; 9 } 10 //定义业务操作 11 public abstract void operate(); 12 13 //内部状态的getter/setter 14 public String getIntrinsic(){ 15 return intrinsic; 16 } 17 18 public void setIntrinsic(String intrinsic) 19 { 20 this.intrinsic = intrinsic; 21 } 22 }View Code
抽象享元角色一般为抽象类,在实际项目中,一般是一个实现类,它是描述一类事物的方法,在抽象角色中,一般需要把外部状态和内部状态定义出来,避免子类随意扩展,下面是具体的享元角色实现的代码:
1 public class ConcreteFlyweight extends Flyweight{ 2 //接受外部状态 3 public ConcreteFlyweight(String extri){ 4 super(extri); 5 } 6 //根据外部状态进行逻辑处理 7 public void operate(){ 8 //业务逻辑 9 } 10 }
这就是实现自己的业务逻辑,然后接收外部的状态,以便内部业务逻辑对外部状态的依赖,在抽象享元中加入final关键字也是有原因的,为了防止无意见修改导致池的混乱。
下面是享元工厂:
1 public FlyweightFactory{ 2 //定义容器 3 private static HashMap<String, Flyweight> pool = new HashMap<>(); 4 //享元工厂 5 public static Flyweight getFlyweight(String extri){ 6 //需要返回的对象 7 Flyweight flyweight = null; 8 //判断是否在池中有该对象 9 if(pool.containskey(extri)){ 10 flyweight = pool.get(extri); 11 } 12 else{ 13 //根据外部状态创建享元对象 14 flyweight = new ConcreteFlyweight(extri); 15 pool.put(extri, flyweight); 16 } 17 return flyweight; 18 } 19 }View Code
通用代码就这么多,可以根据具体需要往里面套~具体的我就不多说了。
当遇到以下情况时,就使用我吧,效果那是杠杠的:
以上。今天就到此为止。荆轲刺秦王,设计模式使我强~
PS:本博客欢迎转发,但请注明博客地址及作者~
博客地址: http://www.cnblogs.com/voidy/
博客新址: http://voidy.gitcafe.com
<。)#)))≦