单例模式:顾名思义,一个程序只有一个实例
多利模式:一个程序有多个实例。
单例模式中,最重要的是如何能够避免多个实例的产生。最直接的方法就是限制使用构造函数,然后定义统一的构造方法。使用《Java设计模式》中皇帝的例子,一般只有一个例子:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * @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("我就是皇帝某某某...."); } }
static 成了这个程序的点睛之笔,同时只能有一个实例,并且通过同一的getInstance来得到该实例
测试程序:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * @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"); } } }
ok,这个程序在多线程下可能出现致命错误,在判断==的时候,可能会有多个线程同时请求,这样的错误无法重现,非常难以查到。作者给了一个通用的例子和改进方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
改进:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
改进方法也很简单,final修饰对象,直接进行定义。然后互斥锁保护返回函数,一切ok,说实在的,比原先的看上去还简单。
设计模式并不难于理解,重要的是能够灵活使用在平时的程序实现中。
下面是多例模式:如果有多个皇帝呢?呵呵,维护一个链表不就行了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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)); } }
注意,作者这里维护的不是一个列表,而是两个,意思差不多,领会精神哈。获得实例的时候,随机获取
测试:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(); } } }
oye,刚打电话把中国移动骂了,感觉不错。真心感觉看《Java设计模式》这本书的收获很大,一些编程的小技巧都很实用。