[DesignPattern] 设计之禅读书笔记(二) 单例模式

  • 单例模式(Singleton Pattern)

    • Ensure a class has only one instance, and provide a global point of access to it.(确保只有一个实例, 而且自行实例化并向整个系统提供这个实例。)
    • 模板
    • 通用代码
    public class Singleton {
        private static final Singleton singleton = new Singleton();
        private Singleton(){}    //限制多个对象产生
    
        //通过该方法获得实例化对象
        public static Singleton getInstance(){ 
            return singleton;
        }
    
        //类中的其他方法,尽量时static
        public static void doSomething() {
    
        }
    }
    
    • 单例模式的优点

      • 节省内存开支
      • 避免资源多重占用
      • 在系统设置全局的访问点,优化和共享资源
    • 单例模式的缺点

      • 单例模式一般没有接口, 扩展很困难, 若要扩展,除了修改代码基本上没有第二种途径可以实现
      • 单例模式对测试时不利的
      • 单例模式与单一职责原则有冲突
    • 单例模式的使用场景

      • 要求生成唯一序列号的环境
      • 在整个项目中需要共享访问点和共享数据,如web计数器,并确保线程安全
      • 创建一个对象需要消耗的资源过多,eg. IO和数据库
      • 需要定义大量静态常量方法(如工具类)的环境, 可以采用单例模式。
    • 单例模式考虑问题

      • 懒汉模式的时候的线程安全问题, 尽量使用饿汉模式
      • 需要考虑对象的复制,解决方法是不提供Cloneable接口
    • 单例的扩展

      • 产生有限个对象 加入数量限制变量
      • 例子
      package shejizhichan.singleton;
      
      import java.util.Random;
      import java.util.Vector;
      
      public class Emperor {
          public static final int maxMumOfEmperor = 2;
          private static Vector<String> names = new Vector<>();
          private static Vector<Emperor> emperors = new Vector<>();
          private static int currentEmperor = 0;
          static {
              for (int i = 0; i < maxMumOfEmperor; i++) {
                  emperors.add(new Emperor("Emperor= " + (i + 1)));
              }
          }
          private Emperor(){}
          private Emperor(String name){
              names.add(name);
          }
      
          public static Emperor getInstance() {
              Random random = new Random();
              currentEmperor = random.nextInt(maxMumOfEmperor);
              return emperors.get(currentEmperor);
          }
      
          public static void say() {
              System.out.println(names.get(currentEmperor));
          }
      
      }
      
      
      package shejizhichan.singleton;
      
      public class Minister {
          public static void main(String[] args) {
              int ministerNum = 5;
              for (int i = 0; i < ministerNum; i++) {
                  Emperor emperor = Emperor.getInstance();
                  System.out.print("No." + (i+1) + " Minister see ");
                  emperor.say();
              }
          }
      }
      
      
    • 最佳实践

      • 单例是比较简单的模式, 在Spring中, 每个Bean默认都是单例, 这样Spring容易就可以管理Bean的生命期。如果采用非单例(Prototype), 则Bean初始化后管理较给J2EE容器。

posted on 2020-10-12 05:34  codingEskimo  阅读(70)  评论(0编辑  收藏  举报

导航