码迷,mamicode.com
首页 > 其他好文 > 详细

Item 3 ------单例模式的几种实现方式,及优缺点

时间:2015-03-21 11:08:03      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

单例模式,是指一个类只有一个唯一的实例,一个类只会被实例化一次。实现这种效果,最佳的方式,编写包含单个元素的枚举类型。

单例模式的最佳实现方式-----创建一个包含单个元素的枚举类

public enum Elvis {
    ONE_INSTANCE;

    public void leaveTheBuilding() {
        System. out.println("Whoa baby, I‘m outta here!" );
    }

}

----------------------------------
public class Test {

    public static void main(String[] args) {
        Elvis elvis = Elvis. ONE_INSTANCE;
        elvis.leaveTheBuilding();
    }
}
优点就是:无偿提供了序列化机制,绝对防止多次实例化,解决每次反序列化一个实例化时,再次创建一个心的实例的问题;并且处理了发射攻击(用户通过反射机制,调用了私有构造器,从而打破只有一个实例的规定).
缺点:Java 1.5开始才支持。
 
通过一个公有的静态成员来实现--唯一的实例,是一个公有的静态成员
public class Elvis {
    public static final Elvis INSTANCE = new Elvis();

    private Elvis() {
    }

    public void leaveTheBuilding() {
        System. out.println("Whoa baby, I‘m outta here!" );
    }

    // This code would normally appear outside the class!
    public static void main(String[] args) {
        Elvis elvis = Elvis. INSTANCE;
        elvis.leaveTheBuilding();
    }
}
缺点:1.存在反射攻击缺陷。要抵御反射攻击,就要记录创建实例的个数,使用一个静态的类成员来保存。当实例个数超过1时,发出异常。2.在序列化一个类时,要添加方法readResolve。添加该方法的目的是,避免每次在反序列化的时候创建一个新的实例。
优点:它的表现简洁明了。
 
通过公有的静态工厂方法
 
public class Elvis {
    private static final Elvis INSTANCE = new Elvis();

    private Elvis() {
    }

    public static Elvis getInstance() {
        return INSTANCE ;
    }

    public void leaveTheBuilding() {
        System. out.println("Whoa baby, I‘m outta here!" );
    }

    // This code would normally appear outside the class!
    public static void main(String[] args) {
        Elvis elvis = Elvis. getInstance();
        elvis.leaveTheBuilding();
    }
}
优点:
将API与实现隔绝开,客户端只管调用getInstance()方法,不管该方法是怎么实现的。如此,你就可以修改getInstance()的实现,而不用考虑客户端是怎么使用的。
比如,它可以被修改为,并不是返回一个唯一的实例;或者修改为,每个线程有一个唯一的实例,在某个线程范围内,该类的实例是唯一的。
 
缺点:
1.存在反射攻击缺陷。要抵御反射攻击,就要记录创建实例的个数,使用一个静态的类成员来保存。当实例个数超过1时,发出异常。
2.在序列化一个类时,要添加方法readResolve。添加该方法的目的是,避免每次在反序列化的时候创建一个新的实例。
解决缺点2的做法:
添加一个readResolve()方法。
public class Elvis implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public static final Elvis INSTANCE = new Elvis();

    private String one;

    private Elvis() {
    }

    public void leaveTheBuilding() {
        System. out.println("Whoa baby, I‘m outta here!" );
    }

    private Object readResolve() {
        // Return the one true Elvis and let the garbage collector
        // take care of the Elvis impersonator.
        return INSTANCE ;
    }

    // This code would normally appear outside the class!
    public static void main(String[] args) {
        Elvis elvis = Elvis. INSTANCE;
        elvis.leaveTheBuilding();
    }
}

  

 

Item 3 ------单例模式的几种实现方式,及优缺点

标签:

原文地址:http://www.cnblogs.com/ttylinux/p/4355241.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!