设计模式之单例模式

来源:互联网 发布:ubuntu 16.04 vi使用 编辑:程序博客网 时间:2024/06/01 18:44

设计模式之单例模式


    单例模式(Single Pattern)定义:Ensurena a class has only one instance, and provide a global point of access to it.(确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例)

通用类:


    Singleton类称为单例类,通过使用private的构造函数,确保了在一个应用中只产生一个实例,并且是自行实例化的,代码:

public class Singleton {private static final Singleton singleton=new Singleton();//限制产生多少个对象private Singleton(){}//通过该方法获得对象实例public static Singleton getSingleton(){return singleton;}//类中其它方法,尽量是staticpublic static void doSomething(){}}

例子:

皇帝类

public class Emperor {private static final Emperor emperor=new Emperor();private Emperor(){}public static Emperor getInstance(){return emperor;}public static void say(){System.out.println("我是皇帝某某某......");}}

臣子类

public class Minister {public static void main(String[] args) {// TODO Auto-generated method stubfor(int day=0;day<3;++day){Emperor emperor=Emperor.getInstance();emperor.say();}}}

单例模式优点

1.在内存中只有一个实例,减少内存开支,当一个对象需要频繁的创建销毁时,并且创建或销毁时性能又无法优化,单例模式的优势就非常明显;

2.单例模式只产生一个实例,减少了系统开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其它依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存来解决;

3.单例模式能够避免对资源的多重占用,如一个写文件动作,由于只有一个实例在内存中,比面对同一个资源文件的同时读写操作;

4.单例模式可以在系统中设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

单例模式的缺点

1.单例模式没有接口,扩展极其困难,若要扩展,除了修改代码基本没有第二种方法;

2.单例模式是对测试不利的;

3.单例模式与单一职责有冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是要单例取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中。

单例模式应用场景

1.要求生成唯一序列号的环境;

2.在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;

3.创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;

4.需要定义大量的静态常量和静态方法的环境。

非线程安全的单例模式

public class Singleton {private static Singleton singleton=null;//限制产生多少个对象private Singleton(){}//通过该方法获得对象实例public static Singleton getSingleton(){if(singleton==null){singleton=new Singleton();}return singleton;}//类中其它方法,尽量是staticpublic static void doSomething(){}}

单例模式的扩展

产生固定数量的皇帝

public class Emperor {//固定产生实例数量private static int maxNumOfEmperor=2;private static ArrayList<String> nameList=new ArrayList<String>();private static ArrayList<Emperor> emperorList=new ArrayList<Emperor>();//当前皇帝序号private static int countNumOfEmperor=0;//产生多有对象static{for(int i=0;i<maxNumOfEmperor;++i){emperorList.add(new Emperor("皇"+(i+1)+"帝"));}}private Emperor(){}private Emperor(String name){nameList.add(name);}public static Emperor getInstance(){Random random=new Random();countNumOfEmperor=random.nextInt(maxNumOfEmperor);return emperorList.get(countNumOfEmperor);}public void say(){System.out.println(nameList.get(countNumOfEmperor));}}

大臣类

public class Minister {public static void main(String[] args) {// TODO Auto-generated method stubint ministerNum=5;for(int i=0;i<ministerNum;++i){Emperor emperor=Emperor.getInstance();System.out.println("第"+(i+1)+"大臣参拜的是:");emperor.say();}}}







0 0
原创粉丝点击