快速理解设计模式之创建模式(下)
在上篇,给大家介绍了简单工厂、工厂方法、抽象工厂3种创建者模式,这3种设计模式如果没真正理解,就很难弄清楚他们的区别。文章没有采用大多数介绍设计模式的篇章介绍各个设计模式的优点、缺点、应用场景,原因是我看过很多关于这样的文章,可是后来一点印象也没有了,而且感觉越看越高深,思想本来挺简单的。我想记录我对设计模式的理解,记录让我真正对某一个设计模式豁然开朗的那种感觉。接下来我们看看创建型模式中的单例模式、建造者模式、原型模式。
1 单例模式
单例模式通俗一点讲就是独一无二的我,只提供一个访问点给你访问我。
例 1:一颗树上有很多苹果,那么苹果这个类就有很多个实例了,所以不能用单例模式。
例 2:一个公司只有一个boss,那么任何职员需要和boss会话,都是和同一个boss会话。
从例2中我们知道,只有一个boss,boss需要提供一个让所有的员工都找到他的方法,找到他就可以和他会话了。我们来UML建模看看。
根据上面的模型,我们来写写伪代码:
单例模式最核心的思想就是把构造函数改为私有private,来实现有且仅有一个实例。
我们讨论设计模式肯定是编程用的,所以我们会遇到多线程这些问题,那么在多线程的时候上面的代码可能就不能保证Boss只有一个了,应为他们可能同时调用findMe,怎么解决这个问题呢?我们会想到加锁。YES。加锁之后如果一个线程A在访问findMe,那么线程B就只能等待了,等线程A解锁之后,线程B访问findMe时由于对象已经创建,所以就不会再重复创建。我们来看看代码:
上面这个代码是由于有多线程这个概念所以我们进行了改进,和设计模式的思想没有关系,看我们编码的功底了。
高手看到上面加锁的代码是不是又有疑问了,当多线程访问findMe()的时候,如果Boss这个实例不为null,由于加锁的原因使得线程需要排队来返回实例,是不是不好呢这样,该怎么解决这个问题。这个好解决,我们判断一下Boss是否为空,如果为空就加锁,不为空就不加锁,就可以解决这个问题了。改进代码如下:
单例扩展:
上述的对象的创建都是在findMe中实现的,我们可不可以在Boss声明的时候直接new呢?答案是可以的,首先我们了解一下sealed、readonly关键字。
readonly常量只能声明为类字段,支持实例类型或静态类型,可以在声明的同时初始化或者在构造函数中进行初始化,初始化完成后便无法更改。
sealed 修饰符可以应用于类、实例方法和属性。密封类不能被继承。
单例另一实现方法如下:
2 建造者模式
建造者模式我的理解就是某某指挥某某做事情。
那我们就对某某指挥某某做事情进行UML建模吧。
下面我们来实现代码:
首先有事情这个对象:
然后是工人相关的对象:
好啦,这些对象都创建好了,就剩下指挥者了,注意了指挥者是指挥某人做事情,这个也要表达出来,我们看看实现。
效果:
效果:
总结:只要我们清楚建造者模式表达的思想是某某指挥某某做事情,那么遇到相似的场景我们都可以用建造者模式,比如以前网上经常举建造者模式例子 如麦当劳、肯德基,收银员点餐、工作人员出餐就是这个思想。
3 原型模式
我们前面已经讲了5种创建型模式了,最后还剩下原型模式。原型模式怎么理解呢?我想大家都知道克隆吧,就是复制一份或者多份一模一样的出来。建模就这样画吧。
原型模式比较简单,相信大家以前看过原型模式讲解的例子也明白了,需要注意的就是浅拷贝与深拷贝的概念。声明:这两个概念和原型设计模式的思想无关,只是因为我们开发语言中有值类型和引用类型导致的。
浅拷贝:通俗一点讲就是引用类型的对象不能被拷贝。
深拷贝:通俗一点讲就是提供了引用类型对象不能被拷贝的解决方案。
我们来看看代码:
浅拷贝克隆:
效果:
看到了吧,如果是浅拷贝,克隆的对象对引用进行赋值,都是对同一个引用对象进行赋值,所以显示出来的结果也是一样的。O(∩_∩)O~
深拷贝克隆:
为了达到真正的完全克隆,我们的解决办法是把引用对象也进行克隆
调用:
效果:
看到上面的结果是否激动了一番,终于实现完美的克隆。好啦,创建型模式就讲到这里了。
我们回顾一下创建型设计模式有哪几种呢?
简单工厂 这个工厂可以生产各种产品
工厂方法(为了解决简单工厂中switch坏味道)
抽象工厂(为了解决几个工厂同时生产某个产品的问题,同时给每个产品加上厂家说明)
单例模式 独一无二的我,只提供一个访问点给你访问我
建造者模式 提供某某指挥某某做事情的模型
原型模式 提供克隆技术给你快速拷贝。
注:本文为作者原创,如下转载请注明出处,http://www.cnblogs.com/programmerblog/admin/EditPosts.aspx?opt=1