




已阅读5页,还剩62页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java设计模式1.1 创建型模式AbstractFactory ( 抽象工厂 ) FactoryMethod ( 工厂方法 ) Singleton ( 单态模式 ) Builder ( 建造者模式 ) Prototype ( 原型模式 ) 1.2 结构型模式Adapter ( 适配器模式 ) Bridge ( 桥接模式 ) Composite ( 组合模式 ) Decorator ( 装配模式 ) Facade ( 外观模式 ) Flyweight ( 享元模式 ) Proxy ( 代理模式 ) 1.3 行为型模式Chain of Responsibility ( 责任链模式 ) Command ( 命令模式 ) Interpreter ( 解释器模式 ) Iterator ( 迭代器模式 ) Mediator ( 中介者模式 ) Memento ( 备忘录模式 ) Observer ( 观察者模式 ) State ( 状态模式 ) Strategy ( 策略模式 ) TemplateMethod ( 模板方法 ) Visitor ( 访问者模式 ) Toney Chen的总结Singleton设计模式 Singleton单类模式是最简单的设计模式,它的主要作用是保证在程序运行生命周期中,使用了单类模式的类只能有一个实例对象存在。单类模式实现了类似C语言中全局变量的功能,单类模式常用于注册/查找的服务。单类模式有两种实现方式:饱汉模式和饿汉模式,如下:饱汉单类模式例子代码:java view plaincopy1. publicclassSingleton12. /饱汉模式,声明时就创建实例对象3. publicstaticfinalSingleton1instance=newSingleton1();4. /单类模式的构造方法必须为private,以避免通过构造方法创建对象实例,5. /并且必须显示声明构造方法,以防止使用默认构造方法6. privateSingleton1()7. /单类模式必须对外提供获取实例对象的方法8. publicstaticSingleton1geInstance()9. returninstance;10. 11. 饿汉单类模式即延迟初始化单类方式,例子代码:java view plaincopy1. publicclassSingleton22. /饿汉模式,声明时不创建实例对象3. publicstaticSingleton2instance;4. /单类模式的构造方法必须为private,以避免通过构造方法创建对象实例,5. /并且必须显示声明构造方法,以防止使用默认构造方法6. privateSingleton2()7. /单类模式必须对外提供获取实例对象的方法,延迟初始化的单类模式必须使用synchronized同步关键字,否则多线程情况下很容易产生多个实例对象8. publicstaticsynchronizedSingleton2geInstance()9. /延迟初始化,只有当第一次使用时才创建对象实例10. if(instance=null)11. returnnewSingleton2();12. 13. returninstance;14. 15. 一般认为饱汉模式要比饿汉模式更加安全。上面两种Singleton单类设计模式的实现方式都隐藏有如下的问题:(1).虽然构造方式的访问修饰符为private,即除了自身以外其他任何类都无法调用,但是通过反射机制的setAccessiable(true)方法可以访问私有方法和属性。因此Singleton单类模式必须考虑这种例外情况。(2).对象序列化之后再反序列化时会生成新的对象,因此当Singleton单类模式类实现序列化接口时,必须显式声明所有的字段为tranisent。在JDK1.5之后引入了Enum枚举,因此在JDK1.5之后Singleton单类模式又有了第三种实现方式,也是最好的实现方式,例子如下:java view plaincopy1. publicenumSingleton32. INSTANCE3. publicvoiddoSomething()4. 5. 6. ;7. publicSingleton3getInstance()8. returnINSTANCE;9. 10. publicabstractvoiddoSomething();11. Singleton单类模式中只有一个INSTANCE枚举元素,枚举可以保证真个程序生命周期中只有一个实例对象存在,同时还避免了常规Singleton单类模式private构造方法被反射调用和序列化问题。注意:java中除了构造方法可以创建对象实例以外,还可以通过克隆方法(clone()是Object中的protected方法)来创建对象, 若单类对象直接继承自Object对象,则如果没有提供具体clone方法实现,则当调用克隆方法创建对象时,会抛出运行时的异常 CloneNotSupportedException。若单类类继承了实现克隆方法的类,则在单类类中必须覆盖父类的克隆方法,显式抛出异常CloneNotSupportedException。另外,实现了单类模式的类不能再有派生子类,因为构造方式是私有的,子类无法调用父类构造方法,因此达到了Final的效果。Proxy设计模式 Proxy代理设计模式是一种控制对象访问的设计模式,类似于网络代理,网络代理机制如下图:Proxy代理设计模式机制如下:客户端程序通过代理程序来访问真正的目标程序,代理程序对外隐藏了目标程序。普通代理设计模式例子代码如下:java view plaincopy1. interfaceProxyBase2. publicvoidf();3. publicvoidg();4. publicvoidh();5. 6. /代理程序7. classProxyimplementProxyBase8. privateProxyBaseimplementation;9. publicProxy()10. /目标程序11. implementation=newProxyImplementation();12. 13. publicvoidf()14. implementation.f();15. 16. publicvoidg()17. implementation.g();18. 19. publicvoidh()20. implementation.h();21. 22. 23. /目标程序24. classProxyImplementationimplementsProxyBase25. publicvoidf()26. System.out.println(“ProxyImplementation.f()”);27. 28. publicvoidg()29. System.out.println(“ProxyImplementation.g()”);30. 31. publicvoidh()32. System.out.println(“ProxyImplementation.h()”);33. 34. 35. /客户端程序调用代理36. publicclassProxyDemo37. publicstaticvoidmain(Stringargs)38. /客户端调用代理程序39. Proxyp=newProxy();40. p.f();41. p.g();42. p.h();43. 44. 从JDK1.3以后,java引入动态代理机制,java的动态代理只能针对接口进行动态代理,即要实现动态代理的类必须实现接口,CGLIB提供了针对类的动态代理功能。JDK动态代理的例子如下:java view plaincopy1. /代理接口2. interfaceFoo3. publicvoidf(Strings);4. publicvoidg(inti);5. publicvoidh(inti,Strings);6. 7. /接口实现类,即被代理类8. classFooImplimplementsFoo9. publicvoidf(Strings)10. System.out.println(“FooImpl.f(),s=”+s);11. 12. publicvoidg(inti)13. System.out.println(“FooImpl.g(),i=”+i);14. 15. publicvoidh(inti,Strings)16. System.out.println(“FooImpl.h(),i=”+i+“,s=”+s);17. 18. 19. /动态代理处理类20. classProxyHandlerimplementsInvocationHandler21. /代理实现类22. privateObjectdelegate;23. publicProxyHandler(Objectobj)24. delegate=obj;25. 26. publicObjectinvoke(Objectproxy,Methodmethod,Objectargs)27. System.out.println(“Beforemothod:”+method);28. method.invoke(this.delegate,args);29. System.out.println(“Aftermothod:”+method);30. returnnull;31. 32. 33. publicclassDynamicProxyDemo34. publicstaticvoidmain(Stringargs)35. Foofoo=newFooImpl();36. ProxyHandlerhandler=newProxyHandler(foo);37. /产生动态代理38. Fooproxy=(Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),newClassFoo.class,handler);39. proxy.f(“f”);40. proxy.g(1);41. proxy.h(“h”,2);42. 43. 动态代理和普通的代理模式的区别:动态代理中的代理类是由java.lang.reflect.Proxy类在运行期时根据接口定义,采用Java 反射功能动态生成的。和java.lang.reflect.InvocationHandler结合,可以加强现有类的方法实现。动态带来自定义 Handler实现InvocationHandler接口,自定义Handler实例化时,将代理的实现类传入自定义Handler对象中。自定义 Handler需要实现invoke方法,该方法可以使用Java反射调用实现类的实现的方法,同时当然可以实现其他功能,例如在调用实现类方法前后加入 Log,实现安全认证等。而Proxy类根据Handler和需要代理的接口动态生成一个接口实现类的对象。当用户调用这个动态生成的实现类时,实际上是 调用了自定义Handler的invoke方法。State设计模式 State状态设计模式类似于Switch多路分支功能的开关,State状态模式机制如下:State状态设计模式用于改变对象的行为,在代理的生命周期里,随着状态变化从一个目标实现程序切换到另一个目标实现程序。我们经常遇到如下的程序代码:java view plaincopy1. publicclassCreature2. privateBooleanisFrog=true;/标识3. publicvoidgreet()4. if(isForg)5. System.out.println(“Ribbet!”);6. else7. System.out.println(“Darling!”);8. 9. 10. /转换标识11. publicvoidkiss()12. isForg=false;13. 14. publicstaticvoidmain(Stringargs)15. Creaturecreature=newCreature();16. creature.greet();17. creature.kiss();18. creature.greet();19. 20. 上面例子代码中greet()方法在执行具体操作之前必须要判断一下标识,代码显得笨拙繁琐,使用简单State状态模式改写上面代码如下:java view plaincopy1. publicclassCreature2. /状态接口3. privateinterfaceState4. Stringresponse();5. 6. privateclassForgimplementsState7. publicStringresponse()8. return“Ribbet!”;9. 10. 11. privateclassPrinceimplementsState12. publicStringresponse()13. return“Darling!”;14. 15. 16. privateStatestate=newForg();17. publicvoidgreet()18. System.out.println(state.response);19. 20. publicvoidkiss()21. state=newPrince();22. 23. publicstaticvoidmain(Stringargs)24. Creaturecreature=newCreature();25. creature.greet();26. creature.kiss();27. creature.greet();28. 29. State状态设计模式中,状态自动切换并传播,不需要再改动标识,代码显得非常优雅。State状态设计模式一个基本框架如下:java view plaincopy1. /状态接口2. interfaceState3. voidoperation1();4. voidoperation2();5. voidoperation3();6. 7. /状态实现类18. classimplementation1implementsState9. publicvoidoperation1()10. System.out.println(“Implementation1.operation1()”);11. 12. publicvoidoperation2()13. System.out.println(“Implementation1.operation2()”);14. 15. publicvoidoperation3()16. System.out.println(“Implementation1.operation3()”);17. 18. 19. /状态实现类220. classimplementation2implementsState21. publicvoidoperation1()22. System.out.println(“Implementation2.operation1()”);23. 24. publicvoidoperation2()25. System.out.println(“Implementation2.operation2()”);26. 27. publicvoidoperation3()28. System.out.println(“Implementation2.operation3()”);29. 30. 31. /服务提供者32. classServiceProvider33. privateStatestate;34. publicServiceProvider(Statestate)35. this.state=state;36. 37. /状态更改38. publicvoidchangeState(StatenewState)39. state=newState;40. 41. publicvoidservice1()42. /43. state.operation1();44. /45. state.operation3();46. 47. publicvoidservice2()48. /49. state.operation1();50. /51. state.operation2();52. 53. publicvoidservice3()54. /55. state.operation3();56. /57. state.operation2();58. 59. 60. publicclassStateDemo61. privateServiceProvidersp=newServiceProvider(newImplementation1();62. privatevoidrun(ServiceProvidersp)63. sp.service1();64. sp.service2();65. sp.service3();66. 67. publicstaticvoidmain(Stringargs)68. StateDemodemo=newStateDemo();69. demo.run(sp);70. sp.changeState(newImplementation2();71. demo.run(sp);72. 73. State状态模式和Proxy代理模式都为客户端程序提供了一个目标程序代理,真正的目标程序被代理所隐藏,当客户端程序调用目标程序时,首先将调用请求发送给代理,代理才真正调用目标程序,但是Proxy代理模式和State状态模式有如下区别:(1).Pro xy代理模式中被调用的目标程序只有一个,而State状态模式中被调用的目标程序有多个。(2).Proxy代理模式的目的是控制客户端对目标程序的访问,而State状态模式是为了根据条件动态改变目标程序。Itrator设计模式 Iterator迭代器模式,提供一种统一的方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节,迭代器模式是为容器而设计。程序对容器对象的访问必然涉及到遍历算法,不同的容器遍历算法是不同的,List,Stack和Set等等常用容器遍历元素的算法各不相同。解决容 器遍历算法差异有两种方案:第一,可以将遍历方法塞到容器对象中去,容器承受了过多的功能,它不仅要负责自己“容器”内的元素维护(添加、删除等等),而 且还要提供遍历自身的接口;第二,根本不提供容器遍历算法,让容器使用者自己去实现。该方法虽然是省事,却又将容器的内部细节暴露无遗。迭代器模式的出 现,很好的解决了上面两种情况的弊端,不但将遍历容器的算法从不同集合容器类中抽象出来,同时又对外隐藏了容器的具体实现细节。迭代器模式由以下角色组成:1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口这个具体迭代器角色于该容器的结构相关。Java集合框架中迭代设计模式的应用:java view plaincopy1. /迭代器,该接口提供了迭代遍历的通用方法2. publicinterfaceIterator3. booleanhasNext();4. Objectnext();5. voidremove();6. 7. /容器迭代化接口,凡是实现此接口的集合容器距可以生成相应的迭代器8. publicinterfaceIterable9. /产生迭代器,将容器对象转换为迭代器对象10. Iteratorinterator();11. 12. /java集合框架的根接口,该接口继承了容器迭代化接口,因此java中的集合都可以被迭代13. publicinterfaceCollectionextendsIterable自定义迭代器,以ArrayList为自定义迭代容器的底层数据结构,实现自定义迭代器的代码如下:java view plaincopy1. publicclassMyIteratorimplementsIterable2. /存放数据的集合3. privateArrayListlist;4. /负责创建具体迭代器角色的工厂方法5. publicIteratoriterator()6. returnnewItr(list);7. 8. /作为内部类的具体迭代器角色9. privateclassItrimplementsIterator10. ArrayListmyList;11. intposition=0;12. publicItr(ArrayListlist)13. this.myList=list;14. 15. publicObjectnext()16. Objectobj=myList.get(position);17. position+;18. returnobj;19. 20. publicbooleanhasNext()21. if(position=myList.size()22. returnfalse;23. else24. returntrue;25. 26. 27. /不支持remove操作28. publicvoidremove()29. thrownewUnsupportedOperationException(30. AlternatingMyIteratordoesnotsupportremove();31. 32. 33. 使用时,MyIterator对象直接调用iterator()方法就可以将自定义容器对象转换为迭代器对象。Iterator模式的优点:(1).实现功能分离,简化容器接口。让容器只实现本身的基本功能,把迭代功能委让给外部类实现,符合类的设计原则。(2).隐藏容器的实现细节。(3).为容器或其子容器提供了一个统一接口,一方面方便调用;另一方面使得调用者不必关注迭代器的实现细节。(4).可以为容器或其子容器实现不同的迭代方法或多个迭代方法。Strategy设计模式 Strategy策略设计模式主要是定义一系列的算法,把这些算法封装成单独的类,在运行时动态选择需要的算法,策略模式机制如下:策略模式例子如下:java view plaincopy1. /文本替换策略2. abstractclassTextStrategy3. protectedStringtext;4. 5. publicTextStrategy(Stringtext)6. this.text=text;7. 8. publicabstractStringreplace();9. 10. /替换算法1:将文本中rn替换为n11. classStrategyOneextendsTextStrategy12. publicStrategyOne(Stringtext)13. super(text);14. 15. publicStringreplace()16. System.out.println(“StrategyOne:”);17. Stringresult=text.replaceAll(rn,n);18. returnresult;19. 20. 21. /替换算法2:将文本中n替换为rn22. classStrategyTwoextendsTextStrategy23. publicStrategyTwo(Stringtext)24. super(text);25. 26. publicStringreplace()27. System.out.println(“StrategyTwo:”);28. Stringresult=text.replaceAll(“n,rn);29. returnresult;30. 31. 32. publicclassTextCharChange33. publicstaticvoidreplace(TextStrategystrategy)34. strategy.replace();35. 36. publicstaticvoidmain(Stringargs)37. StringtestText1=Thisisatesttext!nOh!LineReturn!n;38. StringtestText2=Thisisatesttext!rnOh!LineReturnrn;39. TextCharChange.replace(newStrategyOne(testText2);40. TextCharChange.replace(newStrategyTwo(testText1);41. 42. State状态模式和Strategy策略模式非常类似,但是有如下区别:(1).State状态模式重点在于设定状态变化,根据状态,返回相应的响应。(2).Strategy策略模式重点在于根据需求直接采用设定的策略,即根据场景选择合适的处理算法,而不需要改变状态。Factory设计模式 Factory工厂设计模式为创建对象提供了一种抽象,而对使用者屏蔽了对象创建的具体细节过程,工厂模式有三种:简单工厂模式,抽象工厂模式和工厂方法模式。(1).简单工厂模式:又叫静态工厂模式,简单工厂只包括一个抽象产品类(该类可以是接口,也可以是具体的类),所有需要的产品类都是该抽象产品类的子类。简单工厂模式中工厂为具体产品工厂,产品为抽象产品,由工厂实例创建产品实例:一个生成圆形和矩形的图形工厂,例子如下:java view plaincopy1. /图形接口2. interfaceShape()3. publicvoiddraw();4. 5. /圆形6. classCircleimplementsShape7. publicvoiddraw()8. System.out.println(“Circleisdrawing”);9. 10. 11. /矩形12. classRectangleimplementsShape13. publicvoiddraw()14. System.out.println(“Rectangleisdrawing”);15. 16. 17. /图形工厂18. classShapeFactory19. publicstaticShapecreateShape(Stringname)throwsInstantiationException,20. IllegalAccessException,21. ClassNotFoundException22. 23. /使用java的反射机制来产生对象实例24. return(Shape)class.forName(name).newInstance();25. 26. 27. publicclassShapeDemo28. publicstaticvoiddraw(Shapeshape)29. shape.draw();30. 31. publicstaticvoidmain(Stringargs)32. draw(ShapeFactory.createShape(“Circle”);33. draw(ShapeFactory.createShape(“Rectangle”);34. 35. 图形工厂负责具体图形的对象实例化工作,图形使用者使用时不需要关心图形对象的具体产生过程。(2).抽象工厂模式:抽象工厂模式中可以包括多个抽象产品类,每个抽象产品类可以产生出多个具体产品类,一个抽象工厂用于定义所需产品的组合形式,抽象工厂派生具体工厂类,这些具体工厂类就是简单工厂模式中的工厂类,具体工厂类负责具体产品实例的创建:以软件皮肤为例,软件皮肤由样式style和颜色color组成,实现一套IOS风格的软件皮肤,一套Android风格的软件皮肤,通过抽象工厂实现软件皮肤自由切换例子如下:java view plaincopy1. /软件皮肤类2. classSkin3. privateSkinFactoryskinFactory;4. publicSkin(SkinFactoryfactory)5. setSkinFactory(factory);6. 7. publicvoidsetSkinFactory(SkinFactoryfactory)8. this.skinFactory=factory9. 10. publicvoidshowSkin()11. System.out.println(“Style=”+factory.getStyle().showStyle()+“,color=”+factory.getColor().showColor();12. 13. 14. /软件Style15. interfaceStyle()16. publicvoidshowStyle();17. 18. /IOSstyle19. classIOSStyleimplementsStyle20. publicvoidshowStyle()21. System.out.println(“ThisisIOSstyle”);22. 23. 24. /Androidstyle25. classAndroidStyleimplementsStyle26. publicvoidshowStyle()27. System.out.println(“ThisisAndroidstyle”);28. 29. 30. /软件Color31. interfaceColor()32. publicvoidshowColor();33. 34. /IOScolor35. classIOSColorimplementsColor36. publicvoidshowColor()37. System.out.println(“ThisisIOScolor”);38. 39. 40. /Androidcolor41. classAndroidColorimplementsColor42. publicvoidshowColor()43. System.out.println(“ThisisAndroidcolor”);44. 45. 46. /抽象皮肤工厂47. interfaceSkinFactory48. publicStylegetStyle();49. publicColorgetColor();50. 51. /IOS皮肤工厂52. classIOSSkinFactoryimplementsSkinFactor
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 我的中国梦中学生演讲稿范文5篇
- 卫浴行业售后服务流程与外包合同版本
- 2025年公务员考试备考宝典国考预试题解析与技巧
- (2025年标准)股权过户协议书
- 小学科学二年级上册家校合作计划
- (2025年标准)股分分离协议书
- 2025年工艺行业求职前必看公司面试预测题及应对策略
- 2026届山西省范亭中学高二化学第一学期期中学业水平测试模拟试题含解析
- (2025年标准)股东减持协议书
- 2025年网络安全工程师中级面试技巧与答案
- DB14-T 3398-2025 人社业务就近办服务规范
- 再生资源安全管理制度
- 2025年成都市中考道德与法治试题卷(含答案)
- 采棉机合伙合同范本
- 《小肠的结构与功能》课件
- 教师违反职业道德行为处理办法培训
- 高中生德育教育主题班会
- 婚介服务协议书范本
- 2025届高考作文备考之主题素材:家国情怀
- 蜜雪冰城加盟合同(2025年版)
- ACS合并消化道出血治疗策略
评论
0/150
提交评论