美文网首页Android_Speak
设计模式单例模式

设计模式单例模式

作者: GB_speak | 来源:发表于2017-04-18 13:42 被阅读11次

    1.单利模式的定义及使用场景
    确保某一个类只有一个实例,而且自行示例化并向整个系统提供这个实例。确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象应该有且只有一个。例如创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源,这时就要考虑使用单例模式。

    Paste_Image.png
    2.单例模式的优缺点
    2.1优点
    减少内存,特别是一个对象需要频繁地创建、销毁,而且创建或销毁时性能又无法优化
    单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免同时对一个资源文件的同时写操作
    单例模式可以在系统设置全局的访问点,优化和共享资源访问
    2.2缺点

    单例模式一般没有接口,扩展比较困难
    单例模式与单一责任原则有冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是要单例取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中3.单例模式的实现方式
    3.1懒汉模式

    最原始的懒汉模式
    优点:懒加载
    缺点:未考虑线程安全

    public class Singleton {  
        private static Singleton instance;  
        private Singleton (){}  
      
        public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
        }  
    }```
    加锁的懒汉模式
    优点:懒加载 、线程安全
    
    缺点:效率低
    

    public class Singleton {
    private static Singleton instance;
    private Singleton (){}
    public static synchronized Singleton getInstance() {
    if (instance == null) {
    instance = new Singleton();
    }
    return instance;
    }
    }```
    双重锁懒汉模式
    优点:懒加载、线程安全

    缺点:效率高于2)

    public class Singleton {  
         private volatile static Singleton singleton;  
         private Singleton (){}  
         public static Singleton getSingleton() {  
         if (singleton == null) {  
             synchronized (Singleton.class) {  
             if (singleton == null) {  
                 singleton = new Singleton();  
             }  
             }  
         }  
         return singleton;  
         }  
     }```
    静态内部类
    优点:懒加载、线程安全
    
    缺点:实现方式比较复杂
    

    public class Singleton {
    private static class SingletonHolder {
    private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton (){}
    public static final Singleton getInstance() {
    return SingletonHolder.INSTANCE;
    }
    }```
    3.2饿汉模式

    优点:非懒加载

    缺点:线程安全

    public class Singleton {  
         private Singleton instance = null;  
         static {  
         instance = new Singleton();  
         }  
         private Singleton (){}  
         public static Singleton getInstance() {  
         return this.instance;  
         }  
     }```
    **4.单例模式在Android中的实际应用**
    相信大家对LayoutInflate都不陌生,特别在ListView的Adapter的getView方法中基本都会出现,使用inflate方法去加载一个布局,用于ListView的每个Item的布局。最简单的使用方法是LayoutInflater layoutInflater = LayoutInflater.from(context); 那么Android的源码中是怎么保持LayoutInflater的单例模式呢?分析源码如下:
    

    /**

    • Obtains the LayoutInflater from the given context.
      */
      public static LayoutInflater from(Context context) {
      LayoutInflater LayoutInflater =
      (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      if (LayoutInflater == null) {
      throw new AssertionError("LayoutInflater not found.");
      }
      return LayoutInflater;
      }```
      Context:
    @SuppressWarnings("unchecked")  
    public final <T> T getSystemService(Class<T> serviceClass) {  
    // Because subclasses may override getSystemService(String) we cannot  
    // perform a lookup by class alone. We must first map the class to its  
    // service name then invoke the stringbased method.  
    String serviceName = getSystemServiceName(serviceClass);  
    return serviceName != null ? (T)getSystemService(serviceName) : null;  
    }  
    public abstract String getSystemServiceName(Class<?> serviceClass);```
    ContextImpl:
    

    @Override
    public String getSystemServiceName(Class<?> serviceClass) {
    return SystemServiceRegistry.getSystemServiceName(serviceClass);
    }```
    SystemServiceRegistry :

     /** 
      * Gets the name of the systemlevel service that is represented by the specified class. 
      */  
      public static String getSystemServiceName(Class<?> serviceClass) {  
      return SYSTEM_SERVICE_NAMES.get(serviceClass);  
      }  
    registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,  
      new CachedServiceFetcher<LayoutInflater>() {  
      @Override  
      public LayoutInflater createService(ContextImpl ctx) {  
      return new PhoneLayoutInflater(ctx.getOuterContext());  
      }});  
      
      /** 
      * Statically registers a system service with the context. 
      * This method must be called during static initialization only. 
      */  
      private static <T> void registerService(String serviceName, Class<T> serviceClass,  
      ServiceFetcher<T> serviceFetcher) {  
      SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);  
      SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);  
      }  
      
      static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {  
      private final int mCacheIndex;  
      
      public CachedServiceFetcher() {  
      mCacheIndex = sServiceCacheSize++;  
      }  
      
      @Override  
      @SuppressWarnings("unchecked")  
      public final T getService(ContextImpl ctx) {  
      final Object[] cache = ctx.mServiceCache;  
      synchronized (cache) {  
      // Fetch or create the service.  
      Object service = cache[mCacheIndex];  
      if (service == null) {  
      service = createService(ctx);  
      cache[mCacheIndex] = service;  
      }  
      return (T)service;  
      }  
      }  
      
      public abstract T createService(ContextImpl ctx);  
      }```
    通过源码分析可知,LayoutInflater最终是保存在cache的一个Object数组中,以这种方式进行单例的提供。
    出处:http://huangjunbin.com/page/4/

    相关文章

      网友评论

        本文标题:设计模式单例模式

        本文链接:https://www.haomeiwen.com/subject/xmbfzttx.html