从今天开始打算花上半个月的时间,利用闲暇时间将之前学习过的设计模式进行一个学习笔记的整理,因为前段时间去面试,当问到有关设计模式的时候,毕竟由于时间长了自己给忘了,导致在面试的时候甚是尴尬啊,哪我就选择使用博客的形式将每一种设计模式通过一个博客的形式深入的学习记录一下,这样有我的博客 可以跟面试官说 你可以去看我的博客啊…^_^ 这是后话,最主要是换是自己通过记录达到深入学习的目的啦。
既然这是开头片,哪就侃一侃我对设计模式这个玩意的理解吧。其实很早就知道这个玩意,大学的时候也听别人说这个玩意有多麽的牛逼,多麽的重要,但是从刚一开始参加从左中感受的他的重要性不能说没有,应该说是很小很小。是从什么时候感觉我擦这个玩意还真是挺厉害的哈,是从我开始研究SSM框架的时候,你会发现在框架中几乎所有的设计模式都涉及到了,哪我就在想,这个设计模式到底有多麽好呢。就试着在自己的代码中能够键入某些设计模式,但是。。。。但是。。。发现没有用武之地,可这又是为什么呢,大概是因为自己的能力还没有达到那个境界吧,这就好像是金庸小说里的那些高手,达到了炉火纯青的地步的时候把。但是不管怎样,既然这玩意是古人留下来的,哪我们就有必要去学习,去掌握,虽然现在在自己的代码设计中还用不到,但我相信随着我练级的不断提升我也可以使用的到了。
哈哈哈 上面是为什么要学习的一个背景,大家不知道是因为什么,也有的可能是在想为了面试,为了在面试的时候面试官问的时候我知道,但是在这里我想说句大实话,请问那些面试官我能不能说的上某个设计模式难道真的跟能力有关系吗,个人觉着设计模式这玩意是随着能力的不断提升才能去慢慢的体会,慢慢的掌握的东西,就想我没java程序员刚学习的时候说java或者C++是一门语言,java是面向对象的,没有一定的阅历没有一定的能力对这个的理解是很浅的。。。。。好像扯远了有些抱怨了。但是不管怎么样,我现在就是一个干了三年java的开发者,一下知识站在我三年的经验的基础上的一些拙见,一是为了记录自己的学习成果,二是和大家做一个分享。
下面说一下 这个系列的一个大致的目录吧,咱们就按照从简单到复杂的顺序吧,其实我也是这种顺序学的:
1 单例模式 2 工厂模式,简单工厂模式,抽象工厂模式 3 适配器模式 4 策略模式 5 动态代理模式 6 观察者模式 7 装饰者模式 8 责任链模式 9 组合模式
可能还有其他的哈,因为我暂时先学了这些,就先说这些吧,剩下的一些不常见的模式有空再说,不过我觉着作为一个初级或者中级工程师把这些都掌握了,而不是简单的知道或者死记住,哪基本上也就可以了。。。。
先说第一个吧----单例模式
单例模式顾名思义就是只有一个实例。这在我们的时机项目中其实用到的还是挺多的,比如:java.lang.Runtime,java.net.InetAddress,还有可能我们很少使用的一个枚举类。等等,还比如说我们为了定义以及用来零食存放缓冲数据的一个缓存类就可以做成一个单例模式的。
单例要求这个单例的对象一是自己创建的 而且提供给其他类使用的也必须始终是这一个单例类,就算是在多线程中也应该保持单例。
我们常见的单例模式有三种,当然网上还有的网友说有五种甚至其中,个人觉着那些都是从这三个最基本的衍生出来的。下面我们就将这三种方式创建单例来说一下,然后对比一下这几种方式的优缺点。
首先说有哪三种:懒汉式,饿汉式,枚举式。我们先说懒汉式
懒汉式:
那么什么事懒汉式呢,其实可以根据名字来大概理解,所谓的懒汉指的是我们的单例的实例在创建这个单例类的时候就已经创建好。先看一下懒汉式的java代码的实现:
package cn.com.chnsys.DesignPattern.singleInstance; /** * * <p> * 饿汉式单例模式 * </p> * * 类说明 * * @author duanxj * @version */ public class ReadySingleInstance { /** * 创建类成员变量而且是final的单例对象 */ private static final ReadySingleInstance readySingleInstance = new ReadySingleInstance(); /** * 私有构造方法 */ private ReadySingleInstance() { } /** * 获取单例对象 * * @return */ public ReadySingleInstance getInstance() { return readySingleInstance; } }
上面是饿汉式的单例模式,优点是线程安全,原因是对象是在类加载的时候就已经分配空间创建好,而类的加载只有一次。缺点是浪费内存,原因是不管是否需要,在类加载的时候都对对象进行了堆内存的分配。实际上如果没有使用到这个单例实例的话是浪费内存的。
下面是饱汉模式的单例,当然我这里写的是最经典的饱汉单例模式,还有其他的主要是线程不安全,以及单例实例可能存在多线程中还没有赋值就取出空对象的可能。我在下面写的是经典的。
package cn.com.chnsys.DesignPattern.singleInstance; import com.sun.org.apache.regexp.internal.recompile; /** * * <p> * 饱汉经典单例模式 * </p> * * 类说明 * * @author duanxj * @version */ public class BaoHanSingleInstance { /** * 定义一个单例对象 并且每个线程取的时候都是取变量修改后的值, * 使用volatile保证了多线程访问时instance变量的可见性,避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用 */ private static volatile BaoHanSingleInstance baoHanSingleInstance; /** * 定义一个私有的构造函数 */ private BaoHanSingleInstance() { } /** * 获取单例对象 * * @return */ public static BaoHanSingleInstance getInstance() { // 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率) if (baoHanSingleInstance == null) { ////同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建) synchronized (BaoHanSingleInstance.class) { if (baoHanSingleInstance == null) { ////未初始化,则初始instance变量 baoHanSingleInstance = new BaoHanSingleInstance(); } } } return baoHanSingleInstance; } }
好了上面是对单例模式的一个学习和讲解,其实在所有的设计模式中单例模式应该是最简单的,也是最好理解的。如果只是能够写出单例模式来是不够的,我个人认为要能够写出经典的单例模式,还要明白为什么是经典的,这就需要你对类加载机制和多线程同步安全的知识要有一个掌握。
本来接下来是要学习工厂模式的,但是最近这些天也同时在看springmvc和mina的源码,在看的过程中发现里面使用到了很多的设计模式,比如适配器模式,策略模式,所以想先对这两个设计模式进行一个讲解,然后再说一下观察者模式,这几个说完之后我们再后头来说工厂模式。其实相比与前面三个工厂模式应该是相对来说简单容易理解的。在这里我还想说一句,是什么呢,就是我们再学习设计模式的时候,我认为要不你就在自己的代码中真正的去使用这些设计模式,要不你就去看诸如这些框架啊什么的在哪里使用了这些设计模式,为什么这样使用,使用了有什么模式。而不是单纯的去记而不去理解。鉴于工作经验不是很多的我们要想灵活的在我们的代码中或者设计中使用设计模式还是有点困难的,没关系我们工作经验有限或者知识面有限,我们可以先去看看人家是怎么使用的,使用了后又什么好处,慢慢的我想我们肯定也能在我们的代码设计中灵活的使用这些设计模式。
好了 哪下面就先开始对adapter适配器模式进行学习吧。