[设计模式] 设计模式面面观(3):单件模式(Singletion)-创建型模式
模式分类 载自 : http://blog.csdn.net/fanweiwei/article/details/1794804
从目的上来看
Ø 创建型模式
负责创建对象,封装对象创建行为
Ø 结构模式
处理类与对象间的组合关系
Ø 行为模式
封装类与类间的交互中的职责分配
从范围上来看
Ø 类模式处理类与子类的静态关系
Ø 对象模式处理对象间的动态关系
单件模式(Singletion)-创建型模式
重要声明 :
故事纯属虚构,如有雷同请勿对号入座,故事只是为了抛砖引玉,虽以第一人称和作者本人网名起但不代表本人真实想法,请勿把故事中人物和作者本人联系起来,故事本意只为模式创造前提条件
角色:
ü 皇帝 主演WenSi
ü 贵妃 杨玉环
ü 嫔妃 西施
ü 宫女 小桃红
ü 太监 三德子
ü 官员 A
ü 官员 B
剧情:
开场白:最近迷上了《康熙微服私访记》做了一场白日梦(咨询了一下专业医生做白日梦有利于身心健康)作为至今光棍的我看康熙宫里粉黛3千还在外风流潇洒,自己也过会梦中的皇帝瘾。看看我的后宫生活:
Wensi :三德子
三德子:奴才三德子伺候陛下
Wensi :摆驾嫔妃宫
三德子:咋
到了嫔妃宫………
西施 :嫔妃西施叩见Wensi陛下
Wensi :爱妃请起。
旁白:一阵攀谈后
西施 :夜已深,奴婢伺候Wensi陛下
……………………………………………………………
旁白:天亮上朝,朝堂之上
官员A:陛下陕西今年蝗灾请求朝廷赈灾
Wensi:准奏,命内务府拨银30万两
官员B:陛下江苏今年黄河决堤,请求朝廷赈灾
Wensi:准奏,命内务府拨银300万两(偶老家拨多点哇哈哈)
………………………………………
旁白:众臣商议国家大事,突然宫女小桃红来报
小桃红:皇上,贵妃杨玉环快不行了
Wensi:退潮,三德子摆驾贵妃宫,快快
三德子:咋,皇上摆驾贵妃宫
旁白:来到贵妃宫,见玉环脸色苍白,不忍再看
Wensi:玉环,朕在你身边
杨玉环:陛下,臣妾能在死前再看您一眼,臣妾知足了
旁白:说完玉环香消玉殒
Wensi:玉环(皇帝痛心不已)
旁白:皇帝一声长叹说道
Wensi:三德子摆驾嫔妃宫,找西施玩去。(众人皆倒…………)
呵呵最后搞怪了哈,故事就是故事大家不要浮想联翩哈,这个故事和我们今天要讲的模式有联系吗?有!大家看看我用红色标出来的对话就不难看出。天无二日,国无二君。在中华大地上只有一个皇帝,不会有第二个。不管在什么地方皇帝只有一个那就是我。让我们来看看我们如何用OOD来描述这些呢?
解释下为什么要这样做,用OOD的思想我们先从故事中可以知道一共用了几个角色,上面我已经罗列出来了,他们都是人,他们都有不同的地位(注意我的用此:是,有)。在设计中我们往往会出现具体角色(皇帝、贵妃。。。)直接继承与抽象类 人, 这是不对的!混淆了,is-a和has-a 的概念。地位和人类是聚合关系不是组合关系,就是说一个具体的个人不是生来就是皇帝不是生来就是封疆大吏,皇帝这个称号不是伴随着一个人从生到死,所以他们是地位的一种抽象。但一个人有自己的名字和年龄这个是生来就有的(有人会跟我钻牛脚尖说,人一出生是没有名字的,呵呵有意义吗)伴随着一个人的出生和死亡。
再看地位这个抽象类,因为有地位所以他们能做指挥比他地位低的人做事情所以这里他们共有一个Command方法.
再看接口伺候,皇帝是不用伺候别人的(父母除外)所以我没有把伺候的接口分给皇帝,其他角色都继承了伺候接口,这里是为了让大家理解下抽象和接口的异同何时用哪个更为妥当。
回过头来说说今天我们的主角皇帝,皇帝拥有自高无上的权利,在他的统治范围内不能用第二个皇帝所以他是我们单件模式的主角。老天爷下凡的儿子(即天子)只有一个人所以老天爷派下的皇帝始终都是一个(老天爷即一个简单的造人工厂)。
判定这个OOD设计是否合理我们依据我们第二章的设计模式原则来判定
1. 是否符合开闭原则
我们在新添一个角色敌人成员农民时只要继承地位类和接口伺候就可以了,没有修改任何其他内,同时做到了扩展,所以这个设计完成符合对内修改关闭和对外扩展的开闭原则
答案:符合
2. 是否符合里氏代换原则
我们在用抽现类地位去调用各个角色的Command方法时用具体角色的Command方法代替是没有问题的。
答案:符合
3. 是否符合合成复用原则
上面已经讲述过为何在人和具体角色之间多了地位的抽现类的原因,解释了is-a和has-a区别,所以这也是符合的
答案:符合
4. 是否符合依赖倒置原则
在老天爷这里我们创造出来的具体角色都是用抽象类地位返回的。
答案:符合
5. 是否符合接口隔离原则
皇帝没有继承接口伺候,其他的具体类都有
答案:符合
6. 是否符合抽象原则
不用多讲了
答案:符合
7. 是否符合迪米特法则
因为涉及到的方法很少所以这里看的不是太清楚,这里唯一能看出来的就是皇帝没有伺候的方法,他不关心这个所以也是符合的
答案:符合
总的来讲这个OOD设计是完全符合设计模式的要求的看看,OK下面来研究下皇帝这个单件类的实现。首先我们不能让别人随便的创建(NEW)一个皇帝类所以皇帝类的构造函数是私有的,通过自生一个静态方法提供给外界调用,皇帝类只能生成一次,其余再调用都是调用第一次生成的那个类
总结 :单件模式
意图:
保证一个类仅有一个实例,并提供一个访问它的全局访问点
动机:
项目中经常会有一些特殊需求的类,必须保证他们在系统
中有且只有一个实例,才能确保他们的逻辑的正确性后市良好的效率,如何绕过常规的构造器,提供一种机制来保证一个类的唯一性?
实用性:
l 当类只能有一个实例而且客户可以从一个众所周知的地方访问它
l 当这个唯一实例应该是通过子类化可扩展,并且客户应该无需更改代码就能使用一个扩展的实例时。
结构:
参与者:
Singletion类,在我的CODE中即皇帝类(HuangDi)
效果:
单件模式优点:
1. 对唯一实例的受控访问
2. 缩小名空间:Singletion模式是对全局变量的一种改进,它避免了那些存储唯一实例的全局变量污染名空间。
3. 允许对操作和表示的精化Singletion类可以有子类,而其用这个扩展类的实例来配置一个应用是很容易的,用户可以根据需要配置自己的Singletion子类并做进一步的精化。
4. 允许可变数目的实例:在一些系统里Singletion类也许不需要唯一但需要固定数目的同类所以我们在Singletion类上定义一个阀值控制用户实例的个数。
代码:
http://download.csdn.net/source/251706
http://www.winu.cn/thread-45247-1-1.html
重要补充说明:代码中我只理想的做成单线程实现的在多线程中需要考虑线程问题,控制稍微麻烦点其实只要LOCK一下你的皇帝类中的静态生成皇帝类的方法即可。