JAVA性能优化之设计模式

**设计模式**
设计模式是前人工作的总结和提炼.通常,被人们广泛流传的设计模式都是对于一类问题的成熟的解决方案.如果能合理的使用设计模式,不仅系统能更容易的被人理解,同时还能是系统更加合理的结果.我就归纳了一些设计模式,能够提升软件性能的设计模式.
**单例模式**
单例模式是设计模式中最为普遍的模式之一它是一种对象创建模式.用于一个对象的具体事例,它可以确保系统中一个类只会产生一个该类的实例.在java语言中,这样行为能带来两大好处:
(1)对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言是非常可观的一笔系统开销.
(2)由于new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减少GC压力,缩短GC停顿时间.
因此对于系统的关键组件和被频繁使用的对象,使用单例模式便可以有效的改善系统性能.
单例模式的参与者非常简单.只有单例类和使用者两个,
![单例模式角色](https://img-blog.csdn.net/20151211140854337)
单例模式的核心就是通过一个接口返回唯一的对象实例.
    public class Singleton{
    private Singleton(){
    System.out.println("Singleton is create ");//通过私有化构造方法
}
    private static Singleton instance =new Singleton();
    public static Singleton getinstance(){
    return instance;
}

}

序列化和反序列化可能会破会单例,一般来说,对单例进行序列化和反序列化的场景不多,但如果存在,就要多加注意

public class SerSingleton implements java.io.Serializable{
    String name;
    private SerSingleton(){
    System.out.println("Singleton is create");
    //创建单例的过程可能会比较慢
    name="SerSingleton";
    }
    private static SerSingleton instance=new SerSingleton();
public static SerSingleton getinstance(){
    return instance;
}
public static void createString(){
    System.out.println("createString in Singleton");
}
private Object readResolve(){//阻止生成新的实例,总是返回当前对象
return instance;
}
}

//测试代码
@Test
public void test() throws Exception{
    SerSingleton s1=null;
    SerSingleton s=SerSingleton.getInstance();
    //先将实例化串行化到文件
    FileOutputStream fos=new FileOutputStream("SerSingleton.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(s);
oos.flush();
oos.close();
//从文件读出原有的单例类
FileInputStream fis=new FileInputStream("SerSingleton.txt");
ObjectOutputStream ois=new ObjectOutputStream(fis);
s1=(SerSingleton)ois.readObject();
Assert.assertEquals(s,s1);
}

使用一段代码测试单例的串行化和反串行化,当去掉SerSingleton代码中加粗的readReslove()方法时,以下测试代码抛出异常:
这里写图片描述
说明测试代码中s和s1指向了不同的实例,在反序列化后,生成多个对象实例。而加上readReslove()方法的,程序正常退出.说明,即便经过反序列化,仍然保持了单例的特性.事实上,在实现私有的readReslove()方法后,readObject()已经形同虚设,它直接用readReslove()替换了原本的返回值,从而在形式上的构造了单例.
单例模式详解
代理模式
代理模式也是一种很常见的设计模式.它使用代理对象完成用户的请求,屏蔽了用户对真实对象的访问.就如同现实中的代理一样,代理人被授权执行当事人的一些事宜,而无需当事人出面,从第三方的角度看,似乎当事人并不存在,因为他只和代理人通信.而事实上,代理人只有当事人的授权,并且在核心问题上还需要请示 当事人.
在现实中,使用代理的情况很普遍,而且原因也很多.比如,当事人因为某些隐私不方便出面,或者当事人不具备某些相关的专业技能,而需要一个职业人员来完成一些专业的操作,也可能由于当事人没有时间处理事务,而聘用代理人出面.
在软件设计中,使用代理模式的意图也很多,比如因为安全问题,需要屏蔽客户端的直接访问真实对象,或者在远程调用中,需要使用代理类处理远程方法调用的技术细节(如RMI);也可以是为了提升系统性能,对真实对象进行封装,从而达到延迟加载的目的.通过代理模式实现延迟加载,从而提高系统的性能和反应速度.
1,代理模式的结构
这里写图片描述
以上是一个简单的示例来阐述使用代理模式来实现延迟加载的方法及其意义.假设某客户端软件,有根据用户请求,去数据库查询数据的功能.在查询数据前,需要获取数据库连接,然后软件开始时,初始化系统的所有类,此时尝试获得数据库连接.初始化系统的所有类,此时尝试获得数据库连接.当前系统有大量类似操作存在时(比如xml解析等),所有这些初始化操作的叠加,会使得系统的启动速度变得非常缓慢,为此,使用代理模式,使用代理类,封装对数据库查询中初始化操作,当系统启动时,初始化这个代理类,而非真实的数据库查询类,而代理类什么都没有做,因此,他的构造是相当迅速的.
在系统启动时,将消耗资源最多的方法都使用代理模式分离,就可以加快系统的启动速度,减少用户的等待时间.而在用户真正做查询操作时,再由代理类,单独加载真实的数据库查询类,完成用户的请求,这个过程就是以代理模式实现了延迟加载.
代理模式可以用于多种场合,如用于远程调用的网络代理,考虑安全因素的安全代理等.延迟加载只是代理模式的一种应用场景.
延迟加载的核心思想是:如果当前并没有使用这个组件,则不需要真正的初始化它,使用一个代理对象替换它的原有位置,只有在真正需要使用的时候,才对它进行加载.使用代理模式的延迟加载是非常有意义的, 首先,它可以在时间轴上分散系统压力,尤其是在系统启动时,不必完成所有的初始化工作,从而加速启动时间,其次,很多主题而言,在软甲你启动直到被关闭的整个过程中,根本不会被调用,初始化这些数据无疑是一种资源浪费.显示了使用代理类封装数据库查询的 类后,系统的启动过程.
若系统不适用代理模式,则再启动时就要初始化DBQuery对象,而使用代理模式后,启动时只需要初始化一个轻量级对象DBQueryProxy.
结构图
代理模式详解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章