zoukankan      html  css  js  c++  java
  • 单例模式与多例模式

    单例模式:顾名思义,一个程序只有一个实例

    多利模式:一个程序有多个实例。

    单例模式中,最重要的是如何能够避免多个实例的产生。最直接的方法就是限制使用构造函数,然后定义统一的构造方法。使用《Java设计模式》中皇帝的例子,一般只有一个例子:

    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 中国的历史上一般都是一个朝代一个皇帝,有两个皇帝的话,必然要PK出一个皇帝出来
     */
    public class Emperor {
        private static Emperor emperor = null; // 定义一个皇帝放在那里,然后给这个皇帝名字
    
        private Emperor() {
            // 世俗和道德约束你,目的就是不让你产生第二个皇帝
        }
    
        public static Emperor getInstance() {
    
            if (emperor == null) { // 如果皇帝还没有定义,那就定一个
                emperor = new Emperor();
            }
            return emperor;
        }
    
        // 皇帝叫什么名字呀
        public static void emperorInfo() {
            System.out.println("我就是皇帝某某某....");
        }
    }
    View Code

          static 成了这个程序的点睛之笔,同时只能有一个实例,并且通过同一的getInstance来得到该实例 

          测试程序:

    /**
     * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
     *         all. 大臣是天天要面见皇帝,今天见的皇帝和昨天的,前天不一样那就出问题了!
     */
    @SuppressWarnings("all")
    public class Minister {
        /**
         * @param args
         */
        public static void main(String[] args) {
            // 第一天
            Emperor emperor1 = Emperor.getInstance();
            emperor1.emperorInfo(); // 第一天见的皇帝叫什么名字呢?
            // 第二天
            Emperor emperor2 = Emperor.getInstance();
            Emperor.emperorInfo();
            // 第三天
            Emperor emperor3 = Emperor.getInstance();
            emperor2.emperorInfo();
            // 三天见的皇帝都是同一个人,荣幸吧!
            if(emperor1==emperor2){
                System.out.println("one");
            }
        }
    }
    View Code

          ok,这个程序在多线程下可能出现致命错误,在判断==的时候,可能会有多个线程同时请求,这样的错误无法重现,非常难以查到。作者给了一个通用的例子和改进方法:

    package com.cbf4life.singleton3;
    /**
    * @author cbf4Life cbf4life@126.com
    * I'm glad to share my knowledge with you all.
    * 通用单例模式
    */
    @SuppressWarnings("all")
    public class SingletonPattern {
    private static SingletonPattern singletonPattern= null;
    //限制住不能直接产生一个实例
    private SingletonPattern(){
    }
    public SingletonPattern getInstance(){
    if(this.singletonPattern == null){ //如果还没有实例,则创建一个
    this.singletonPattern = new SingletonPattern();
    }
    return this.singletonPattern;
    }
    }
    View Code

          改进:

    package com.cbf4life.singleton3;
    /**
    * @author cbf4Life cbf4life@126.com
    * I'm glad to share my knowledge with you all.
    * 通用单例模式
    */
    @SuppressWarnings("all")
    public class SingletonPattern {
    private static final SingletonPattern singletonPattern= new
    SingletonPattern();
    //限制住不能直接产生一个实例
    private SingletonPattern(){
    }
    public synchronized static SingletonPattern getInstance(){
    return singletonPattern;
    }
    }
    View Code

          改进方法也很简单,final修饰对象,直接进行定义。然后互斥锁保护返回函数,一切ok,说实在的,比原先的看上去还简单。

          设计模式并不难于理解,重要的是能够灵活使用在平时的程序实现中。

          下面是多例模式:如果有多个皇帝呢?呵呵,维护一个链表不就行了

    package com.cbf4life.singleton2;
    import java.util.ArrayList;
    import java.util.Random;
    /**
    * @author cbf4Life cbf4life@126.com
    * I'm glad to share my knowledge with you all.
    * 中国的历史上一般都是一个朝代一个皇帝,有两个皇帝的话,必然要PK出一个皇帝出来。
    * 问题出来了:如果真在一个时间,中国出现了两个皇帝怎么办?比如明朝土木堡之变后,
    * 明英宗被俘虏,明景帝即位,但是明景帝当上皇帝后乐疯了,竟然忘记把他老哥明英宗削为太上皇,
    * 也就是在这一个多月的时间内,中国竟然有两个皇帝!
    *
    */16 页
    您的设计模式
    @SuppressWarnings("all")
    public class Emperor {
    private static int maxNumOfEmperor = 2; //最多只能有连个皇帝
    private static ArrayList emperorInfoList=new ArrayList(maxNumOfEmperor); //
    皇帝叫什么名字
    private static ArrayList emperorList=new ArrayList(maxNumOfEmperor); //装皇
    帝的列表;
    private static int countNumOfEmperor =0; //正在被人尊称的是那个皇帝
    //先把2个皇帝产生出来
    static{
    //把所有的皇帝都产生出来
    for(int i=0;i<maxNumOfEmperor;i++){
    emperorList.add(new Emperor("皇"+(i+1)+"帝"));
    }
    }
    //就这么多皇帝了,不允许再推举一个皇帝(new 一个皇帝)
    private Emperor(){
    //世俗和道德约束你,目的就是不让你产生第二个皇帝
    }
    private Emperor(String info){
    emperorInfoList.add(info);
    }
    public static Emperor getInstance(){
    Random random = new Random();
    countNumOfEmperor = random.nextInt(maxNumOfEmperor); //随机拉出一个皇帝,
    只要是个精神领袖就成
    return (Emperor)emperorList.get(countNumOfEmperor);
    }
    //皇帝叫什么名字呀
    public static void emperorInfo(){
    System.out.println(emperorInfoList.get(countNumOfEmperor));
    }
    }
    View Code

          注意,作者这里维护的不是一个列表,而是两个,意思差不多,领会精神哈。获得实例的时候,随机获取

          测试:

    package com.cbf4life.singleton2;
    /**
    * @author cbf4Life cbf4life@126.com
    * I'm glad to share my knowledge with you all.
    * 大臣们悲惨了,一个皇帝都伺候不过来了,现在还来了两个个皇帝
    * TND,不管了,找到个皇帝,磕头,请按就成了!
    */
    @SuppressWarnings("all")
    public class Minister {
    /**
    * @param args
    */
    public static void main(String[] args) {
    int ministerNum =10; //10个大臣
    for(int i=0;i<ministerNum;i++){
    Emperor emperor = Emperor.getInstance();
    System.out.print("第"+(i+1)+"个大臣参拜的是:");
    emperor.emperorInfo();
    }
    }
    }
    View Code

          oye,刚打电话把中国移动骂了,感觉不错。真心感觉看《Java设计模式》这本书的收获很大,一些编程的小技巧都很实用。

        

  • 相关阅读:
    操作系统——死锁相关
    Java 实现广度优先搜索和深度优先搜索
    Java 实现常见排序算法
    初次接触JQuery
    Firefox使用stylish自定义网页背景
    使用randoop自动化生成测试用例
    软件测试(五)——使用Selenium IDE进行自动化测试
    软件项目管理(二)——用jenkins持续集成、Maven、Github的使用
    云计算(一)——使用 Hadoop Mapreduce 进行数据处理
    软件测试(四)——图覆盖
  • 原文地址:https://www.cnblogs.com/Joy06/p/3672582.html
Copyright © 2011-2022 走看看