设计模式

yulongblue

贡献于2011-09-10

字数:11908 关键词: 设计模式 Java

起个名字吧,没想好 第 1 页 目目目目 录录录录 1. 策略模式 ........................................................................................... 2 2. 代理模式 ........................................................................................... 6 3. 单例模式 ......................................................................................... 10 4. 多例模式 ......................................................................................... 12 起个名字吧,没想好 第 2 页 1. 策略模式策略模式策略模式策略模式 刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开 解决棘手问题,嘿,还别说,真是解决了大问题,搞到最后是周瑜陪了夫人又折兵呀,那咱 们先看看这个场景是什么样子的。 先说这个场景中的要素:三个妙计,一个锦囊,一个赵云,妙计是小亮同志给的,妙计 是放置在锦囊里,俗称就是锦囊妙计嘛,那赵云就是一个干活的人,从锦囊中取出妙计,执 行,然后获胜,用 JAVA 程序怎么表现这个呢? 三个妙计是同一类型的东东,那咱就写个接口: package com.cbf4life.strategy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 首先定一个策略接口,这是诸葛亮老人家给赵云的三个锦囊妙计的接口 * */ public interface IStrategy { // 每个锦囊妙计都是一个可执行的算法 public void operate(); } 然后再写三个实现类,有三个妙计嘛: package com.cbf4life.strategy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 找乔国老帮忙,使孙权不能杀刘备 */ public class BackDoor implements IStrategy { public void operate() { System. out .println( “找乔国老帮忙,让吴国太给孙权施加压力“); } } 起个名字吧,没想好 第 3 页 package com.cbf4life.strategy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 求吴国太开个绿灯 */ public class GivenGreenLight implements IStrategy { public void operate() { System. out .println( “求吴国太开个绿灯,放行!“); } } package com.cbf4life.strategy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 孙夫人断后,挡住追兵 */ public class BlockEnemy implements IStrategy { public void operate() { System. out .println( “孙夫人断后,挡住追兵“); } } 好了,大家看看,三个妙计是有了,那需要有个地方放这些妙计呀,放锦囊呀: 起个名字吧,没想好 第 4 页 package com.cbf4life.strategy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 计谋有了,那还要有锦囊 */ public class Context { // 构造函数,你要使用那个妙计 private IStrategy straegy ; public Context(IStrategy strategy){ this .straegy = strategy; } // 使用计谋了,看我出招了 public void operate(){ this .straegy .operate(); } } 然后就是赵云雄赳赳的揣着三个锦囊,拉着已步入老年行列的、还想着娶纯情少女的、 色迷迷的刘老爷子去入赘了,嗨,还别说,小亮的三个妙计还真是不错,瞅瞅: package com.cbf4life.strategy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. */ public class ZhaoYun { /** * 赵云出场了,他根据诸葛亮给他的交代,依次拆开妙计 */ public static void main(String[] args) { Context context; // 刚刚到吴国的时候拆第一个 System. out .println( “----------- 刚刚到吴国的时候拆第一个 -------------“); context = new Context( new BackDoor()); // 拿到妙计 context.operate(); // 拆开执行 System. out .println( “\n\n\n\n\n\n\n\n“ ); 起个名字吧,没想好 第 5 页 // 刘备乐不思蜀了,拆第二个了 System. out .println( “----------- 刘备乐不思蜀了,拆第二个了 -------------“); context = new Context( new GivenGreenLight()); context.operate(); // 执行了第二个锦囊了 System. out .println( “\n\n\n\n\n\n\n\n“ ); // 孙权的小兵追了,咋办?拆第三个 System. out .println( “----------- 孙权的小兵追了,咋办?拆第三个 -------------“); context = new Context( new BlockEnemy()); context.operate(); // 孙夫人退兵 System. out .println( “\n\n\n\n\n\n\n\n“ ); /* *问题来了:赵云实际不知道是那个策略呀,他只知道拆第一个锦囊, *而不知道是BackDoor 这个妙计,咋办? 似乎这个策略模式已经把计谋名称 写出来了 * * 错!BackDoor 、GivenGreenLight 、BlockEnemy 只是一个代码,你写成 first 、second 、third ,没人会说你错! * * 策略模式的好处就是:体现了高内聚低耦合的特性呀,缺点嘛,这个那个,我 回去再查查 */ } } 就这三招,搞的周郎是“陪了夫人又折兵”呀!这就是策略模式,想要类图,baidu 上 google 一下,能查到一大堆策略模式的类图,纯技术的东西咱不说行不~ 起个名字吧,没想好 第 6 页 2. 代理模式代理模式代理模式代理模式 什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代 理人总要知道被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代 理人虽然不能干活,但是被代理的人能干活呀。 比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理,表现在程 序上时这样的: 先定义一种类型的女人: package com.cbf4life.proxy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 定义一种类型的女人,王婆和潘金莲都属于这个类型的女人 */ public interface KindWomen { // 这种类型的女人能做什么事情呢? public void makeEyesWithMan(); // 抛媚眼 public void happyWithMan(); //happy what? You know that! } 一种类型嘛,那肯定是接口,然后定义潘金莲: package com.cbf4life.proxy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 定一个潘金莲是什么样的人 */ public class PanJinLian implements KindWomen { public void happyWithMan() { System. out .println( “潘金莲在和男人做那个.....“); } 起个名字吧,没想好 第 7 页 public void makeEyesWithMan() { System. out .println( “潘金莲抛媚眼“); } } 再定一个丑陋的王婆: package com.cbf4life.proxy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 王婆这个人老聪明了,她太老了,是个男人都看不上, * 但是她有智慧有经验呀,她作为一类女人的代理! */ public class WangPo implements KindWomen { private KindWomen kindWomen ; public WangPo(){ // 默认的话,是潘金莲的代理 this .kindWomen = new PanJinLian(); } // 她可以是KindWomen 的任何一个女人的代理,只要你是这一类型 public WangPo(KindWomen kindWomen){ this .kindWomen = kindWomen; } public void happyWithMan() { this .kindWomen .happyWithMan(); // 自己老了,干不了,可以让年轻的 代替 } public void makeEyesWithMan() { this .kindWomen .makeEyesWithMan(); // 王婆这么大年龄了,谁看她抛 媚眼?! } } 两个女主角都上场了,男主角也该出现了: 起个名字吧,没想好 第 8 页 package com.cbf4life.proxy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 定义一个西门庆,这人色中饿鬼 */ public class XiMenQing { /* * 水浒里是这样写的:西门庆被潘金莲用竹竿敲了一下难道,痴迷了, * 被王婆看到了, 就开始撮合两人好事,王婆作为潘金莲的代理人 * 收了不少好处费,那我们假设一下: * 如果没有王婆在中间牵线,这两个不要脸的能成吗?难说的很! */ public static void main(String[] args) { // 把王婆叫出来 WangPo wangPo = new WangPo(); // 然后西门庆就说,我要和潘金莲happy ,然后王婆就安排了西门庆丢筷子的那 出戏: wangPo.makeEyesWithMan(); // 看到没,虽然表面上时王婆在做,实际是 爽的是潘金莲 wangPo.happyWithMan(); } } 那这就是活生生的一个例子,通过代理人实现了某种目的,如果真去掉王婆这个中间环 节,直接是西门庆和潘金莲勾搭,估计很难成就武松杀嫂事件。 那我们再考虑一下,水浒里还有没有这类型的女人?有,卢俊义的老婆贾氏(就是和那 个固管家苟合的那个),这名字起的:“假使”,那我们也让王婆做她的代理: 把贾氏素描出来: package com.cbf4life.proxy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. */ public class JiaShi implements KindWomen { public void happyWithMan() { System. out .println( “贾氏正在Happy 中......“); 起个名字吧,没想好 第 9 页 } public void makeEyesWithMan() { System. out .println( “贾氏抛媚眼“); } } 西门庆勾贾氏: package com.cbf4life.proxy; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 定义一个西门庆,这人色中饿鬼 */ public class XiMenQing { public static void main(String[] args) { // 改编一下历史,贾氏被西门庆勾走: JiaShi jiaShi = new JiaShi(); WangPo wangPo = new WangPo(jiaShi); // 让王婆作为贾氏的代理人 wangPo.makeEyesWithMan(); wangPo.happyWithMan(); } } 说完这个故事,那额总结一下,代理模式主要使用了 Java 的多态,干活的是被代理类, 代理类主要是接活,你让我干活,好,我交给幕后的类去干,你满意就成,那怎么知道被代 理类能不能干呢?同根就成,大家知根知底,你能做啥,我能做啥都清楚的很,同一个接口 呗。 起个名字吧,没想好 第 10 页 3. 单例模式单例模式单例模式单例模式 这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此的广泛, 如此的有人缘,单例就是单一、独苗的意思,那什么是独一份呢?你的思维是独一份,除此 之外还有什么不能山寨的呢?我们举个比较难复制的对象:皇帝 中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单 例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝 应该和昨天、前天的一样(过渡期的不考虑,别找茬哦),大臣磕万头后,抬头一看,嗨, 还是昨天那个皇帝,单例模式,绝对的单例模式: 先定一个皇帝: package com.cbf4life.singleton1; /** * @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( “我就是皇帝某某某....“); } } 然后定义大臣: package com.cbf4life.singleton1; 起个名字吧,没想好 第 11 页 /** * @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 (); // 三天见的皇帝都是同一个人,荣幸吧! } } 看到没,大臣天天见到的都是同一个皇帝,不会产生错乱情况,反正都是一个皇帝,是 好是坏就这一个,只要提到皇帝,大家都知道指的是谁,清晰,而又明确。问题是这是通常 情况,还有个例的,如同一个时期同一个朝代有两个皇帝,怎么办? 起个名字吧,没想好 第 12 页 4. 多例模式多例模式多例模式多例模式 这种情况有没有?有!大点声,有没有? 有!,是,确实有,就出现在宋朝,那三国期 间的算不算,不算,各自称帝,各有各的地盘,国号不同。大家还记得那首诗《石灰吟》吗? 作者是谁?于谦,他是被谁杀死的?明英宗朱祁镇,对,就是那个在土木堡之变中被瓦刺俘 虏的皇帝,被俘虏后,他弟弟朱祁钰当上了皇帝,就是明景帝,估计当上皇帝后乐疯了,忘 记把朱祁镇削为太上皇了,我Shit ,在中国的历史上就这个时期是有2个皇帝,你说这期间 的大臣多郁闷,两个皇帝耶,两个精神依附对象呀。 这个场景放到我们设计模式中就是叫有上限的多例模式(没上限的多例模式太容易了, 和你直接new 一个对象没啥差别,不讨论)怎么实现呢,看我出招: 把两个皇帝定义出来: 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 出一个皇帝出来。 * 问题出来了:如果真在一个时间,中国出现了两个皇帝怎么办?比如明朝土木堡之变后, * 明英宗被俘虏,明景帝即位,但是明景帝当上皇帝后乐疯了,竟然忘记把他老哥明英宗 削为太上皇, * 也就是在这一个多月的时间内,中国竟然有两个皇帝! * */ @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)+ “帝“)); } 起个名字吧,没想好 第 13 页 } // 就这么多皇帝了,不允许再推举一个皇帝(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 )); } } 那大臣是比较悲惨了,两个皇帝呀,两个老子呀,怎么拜呀,不管了,只要是个皇帝就 成: 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) { 起个名字吧,没想好 第 14 页 int ministerNum =10; //10 个大臣 for (int i=0;i

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ] 4 人已下载

下载文档

相关文档