android源码之单列

来源:互联网 发布:免费电话会议软件 编辑:程序博客网 时间:2024/05/29 03:38

模式的定义:
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

使用场景
确保某个类有且只有一个对象的场景。

UML类图
这里写图片描述

简单示例:
单例模式是设计模式中最简单的,只有一个单例类,没有其他的层次结构与抽象。该模式需要确保该类只能生成一个对象,通常是该类需要消耗太多的资源或者没有没有多个实例的理由。例如一个公司只有一个CEO、一台电脑通常只有一个显示器等。下面我们以公司里的CEO为例来简单演示一下,一个公司可以有几个VP,无数个员工,但是CEO只有一个,请看下面的实现代理 :
package com.dp.example.singleton;
/**
* 人的基类
* @author mrsimple
*
*/
public abstract class Person {
public abstract void talk() ;
}

// 普通员工
public class Staff extends Person {

@Override  public void talk() {  }  

}

// 副总裁
public class VP extends Person {

@Override  public void talk() {  }  

}

// CEO, 单例模式
public class CEO extends Person {

private static final CEO mCeo = new CEO();  private CEO() {  }  public static CEO getCeo() {      return mCeo;  }  @Override  public void talk() {      System.out.println("CEO发表讲话");  }  

}

// 公司类
import java.util.ArrayList;
import java.util.List;

public class Company {
private List allPersons = new ArrayList();

public void addStaff(Person per) {      allPersons.add(per);  }  public void showAllStaffs() {      for (Person per : allPersons) {          System.out.println("Obj : " + per.toString());      }  }  

}

// test
public class Test {
public static void main(String[] args) {
Company cp = new Company() ;
Person ceo1 = CEO.getCeo() ;
Person ceo2 = CEO.getCeo() ;
cp.addStaff(ceo1);
cp.addStaff(ceo2);

    Person vp1 = new VP() ;      Person vp2 = new VP() ;      Person staff1 = new Staff() ;      Person staff2 = new Staff() ;      Person staff3 = new Staff() ;      cp.addStaff(vp1);      cp.addStaff(vp2);      cp.addStaff(staff1);      cp.addStaff(staff2);      cp.addStaff(staff3);      cp.showAllStaffs();  }  

}

单列模式的几种实现方法:
package com.dp.example.singleton;

public class Singleton {
private static Singleton mInstance = null;

private Singleton() {  }  public void doSomething() {      System.out.println("do sth.");  }  /**  * 方式二、double-check, 避免并发时创建了多个实例, 该方式不能完全避免并发带来的破坏.  *   * @return  */  public static Singleton getInstance() {      if (mInstance == null) {          synchronized (Singleton.class) {              if (mInstance == null) {                  mInstance = new Singleton();              }          }      }      return mInstance;  }  /**  * 方式三 : 在第一次加载SingletonHolder时初始化一次mOnlyInstance对象, 保证唯一性, 也延迟了单例的实例化,  * 如果该单例比较耗资源可以使用这种模式.  *   * @return  */  public static Singleton getInstanceFromHolder() {      return SingletonHolder.mOnlyInstance;  }  /**  * 静态内部类  *   * @author mrsimple  *  */  private static class SingletonHolder {      private static final Singleton mOnlyInstance = new Singleton();  }  /**  *  方式四 : 枚举单例, 线程安全  * @author mrsimple  *  */  enum SingletonEnum {      INSTANCE;      public void doSomething() {          System.out.println("do sth.");      }  }  /**  * 方式五 : 注册到容器, 根据key获取对象.一般都会有多种相同属性类型的对象会注册到一个map中  * instance容器  */  private static Map<string singleton=""> objMap = new HashMap<string singleton="">();  /**  * 注册对象到map中  * @param key  * @param instance  */  public static void registerService(String key, Singleton instance) {      if (!objMap.containsKey(key) ) {          objMap.put(key, instance) ;      }  }  /**  * 根据key获取对象  * @param key  * @return  */  public static Singleton getService(String key) {      return objMap.get(key) ;  }  

}

优点与缺点
优点 :
1、由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。
2、由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决;
3、单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
4、单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

缺点 :
1、单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。
2、单例模式与单一职责原则有冲突。

0 0