单例模式与多例模式

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

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

单例模式中,最重要的是如何能够避免多个实例的产生。最直接的方法就是限制使用构造函数,然后定义统一的构造方法。使用《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设计模式》这本书的收获很大,一些编程的小技巧都很实用。

    

原文地址:https://www.cnblogs.com/Joy06/p/3672582.html