23种设计模式
创建型模式 | 结构型模式 | 行为型模式 |
---|---|---|
简单工厂模式 抽象工厂模式 工厂方法模式 建造者模式 单例模式 原型模式 |
适配器模式 外观模式 装饰器模式 桥接模式 享元模式 代理模式 组合模式 |
模板方法模式 观察者模式 迭代器模式 责任链模式 备忘录模式 命令模式 状态模式 访问者模式 中介者模式 策略模式 解释器模式 |
创建型模式(CreateingPattern)
帮助我们创建对象
简单工厂模式(SimpleFactory)
简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例
用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)
工厂方法模式(Factory)
用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂模式(AbstractFactory)
用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
- 工厂模式应用场景
– JDK中Calendar的getInstance方法
– JDBC中Connection对象的获取
– Hibernate中SessionFactory创建Session
– spring中IOC容器创建管理bean对象
– XML解析时的DocumentBuilderFactory创建解析器对象
– 反射中Class对象的newInstance()
建造者模式(Builder)
分离了对象子组件的单独构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。
- 应用场景
– StringBuilder类的append方法
– SQL中的PreparedStatement
– JDOM中DomBuilder、SAXBuilder
单件模式(Singleton)
保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
- 常见的五种单例模式实现方式:
– 主要:
• 饿汉式(线程安全,调用效率高。 但是,不能延时加载。)
• 懒汉式(线程安全,调用效率不高。 但是,可以延时加载。)
– 其他:
• 双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)
• 静态内部类式(线程安全,调用效率高。 但是,可以延时加载)
• 枚举单例(线程安全,调用效率高,不能延时加载) - 应用场景
– Windows的Task Manager(任务管理器)
– Windows的Recycle Bin(回收站)
– 项目中,读取配置文件的类
– 网站的计数器
– 应用程序的日志应用(共享的日志文件一直处于打开状态,只能有一个实例去操作, 否则内容不好追加)
– 数据库连接池的设计一般采用单例模式
– 操作系统的文件系统,一个操作系统只能有一个文件系统。
– Application 也是单例应用(Servlet编程)
– 在Spring中,每个Bean默认是单例的,这样做的优点是Spring容器可以管理
– 在Servlet编程中,每个Servlet是单例
– 在Spring MVC框架/Struts1框架中,控制器对象是单例
原型模式(Prototype)
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
- 应用场景
– 原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
Spring中bean的创建实际就是两种:单例模式和原型模式。(当然,原型模式需要和工厂模式搭配起来)
结构型模式(StructuralPattern)
是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。关注对象和类的组织
适配器模式(Adapter)
将一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容不能一起工作的类可以一起工作
- 应用场景
– 经常用来做旧系统改造和升级
– java.io.InputStreamReader(InputStream)
– java.io.OutputStreamWriter(OutputStream)
外观模式(Facade)
为子系统提供统一的调用接口,使得子系统更加容易使用
- 应用场景
– JDBC封装后的,commons提供的DBUtils类,Hibernate提供的工具类、Spring JDBC工具类等
装饰模式(Decorator)
动态地给一个对象添加额外的功能,比继承灵活
- 应用场景
– IO中输入流和输出流的设计
– Swing包中图形界面构件功能
– Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper 类,增强了request对象的功能。
– Struts2中,request,response,session对象的处理
桥接模式(Bridge)
处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。
- 应用场景
– JDBC驱动程序
– AWT中的Peer架构
– 银行日志管理:格式分类和距离分类
– 人力资源系统中的奖金计算模块:奖金分类和部门分类
– OA系统中的消息处理:业务类型和发送消息方式
享元模式(FlyWeight)
运用共享技术有效的实现管理大量细粒度对象,节省内存,提高效率
- 应用场景
– 享元模式由于其共享的特性,可以在任何“池”中操作(线程池、数据库连接池)
– String类
代理模式(Proxy)
为真实对象提供一个代理,从而控制对真实对象的访问, AOP的核心实现机制
-
分类:
– 静态代理(静态定义代理类)
– 动态代理(动态生成代理类)
• JDK自带的动态代理
• javaassist字节码操作库实现
• CGLIB
• ASM(底层使用指令,可维护性较差) -
作用:
– 安全代理:屏蔽对真实角色的直接访问。
– 远程代理:通过代理类处理远程方法调用(RMI)
– 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。 比如开发一个大文档查看软件,大文档中有大的图片,在打开文件时不可能将所有的图片都显示出来,可以使用代理模式,当需要查看图片时,用proxy来进行大图片的打开。 -
应用场景:
– struts2中拦截器的实现
– 数据库连接池关闭处理
– Hibernate中延时加载的实现
– mybatis中实现拦截器插件
– AspectJ的实现
– spring中AOP的实现(日志拦截,声明式事务处理)
– web service
– RMI远程方法调用
组合模式(Composite)
将对象组合成树状结构以表示”部分和整体”层次结构,使得客户可以统一的调用叶子对象和容器对象
- 应用场景
– 操作系统的资源管理器
– GUI中的容器层次图
– XML文件解析
– OA系统中,组织结构的处理
– Junit单元测试框架:底层设计是典型的组合模式,TestCase(叶子)、TestUnite(容器)、Test接口(抽象)
行为型模式(BehavioralPattern)
关注系统中对象之间的相互交互, 研究系统在运行时对象之间的相互通信和协作, 进一步明确对象的职责
模板模式(TemplateMethod)
定义一个操作的算法骨架,将某些易变的步骤延迟到子类中实现
-
应用场景
– 数据库访问的封装
– Junit单元测试
– Servlet中关于doGet/doPost方法调用
– Hibernate中模板程序
– Spring中JDBCTemplate , HibernateTemplate等
观察者模式(Oberserver)
当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新
- 应用场景
– 聊天室程序的,服务器转发给所有客户端
– 网络游戏(多人联机对战)场景中,服务器将客户端的状态进行分发
– 邮件订阅
– Servlet中,监听器的实现
– Android中,广播机制
– JDK的AWT中事件处理模型,基于观察者模式的委派事件模型(Delegation Event Model)
• 事件源----------------目标对象 • 事件监听器------------观察者
– 京东商城中,群发某商品打折信息
迭代子模式(Iterator)
提供一种可以遍历聚合对象的方式。又称为:游标cursor模式
- 应用场景
– JDK内置的迭代器(List/Set)
责任链模式(ChainOfResponsibility)
避免请求发送者和接收者耦合,让多个对象都有可能接收请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理为止
- 应用场景
– Java中,异常机制就是一种责任链模式。一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch.
– Javascript语言中事件的冒泡和捕获机制, Java语言中事件的处理都采用观察者模式。
– Servlet开发中,过滤器的链式处理
– Struts2中,拦截器的调用也是典型的责任链模式
备忘录模式(Memento)
捕获一个对象的内部状态,并保存之;需要时,可以恢复到保存的状态
- 应用场景
– 棋类游戏中的,悔棋
– 普通软件中的,撤销操作
– 数据库软件中的,事务管理中的,回滚操作
– Photoshop软件中的,历史记录
命令模式 (Command)
将一个请求封装为一个对象,从而使得请求调用者和请求接收者解耦
- 应用场景
– Struts2中action的整个调用过程中就有命令模式。
– 数据库事务机制的底层实现
– 命令的撤销和恢复
状态模式(State)
允许一个对象在其内部状态改变时改变它的行为
- 应用场景
– 银行系统中账号状态的管理
– OA系统中公文状态的管理
– 酒店系统中房间状态的管理
– 线程对象各状态之间的切换
访问者模式(Visitor)
表示一个作用于某对象结构中的各元素的操作,它使得用户可以在不改变各元素的类的前提下定义作用于这些元素的新操作
- 应用场景(应用范围非常窄)
– XML文档解析器设计
– 编译器的设计
– 复杂集合对象的处理
中介者模式(Mediator)
通过一个中介对象来封装一系列的对象交互,使得各对象不需要相互引用
- 应用场景
– MVC模式(其中的C:控制器就是一个中介者对象。M和V都和他打交道)
– 窗口游戏程序,窗口软件开发中窗口对象也是一个中介者对象
– 图形界面开发GUI中,多个组件之间的交互,可以通过引入一个中介者对象来解决,可以是整体的窗口对象或者DOM对象
– Java.lang.reflect.Method#invoke()
策略模式(Strategy)
定义一系列算法,并将每个算法封装在一个类中
- 应用场景
– GUI编程中,布局管理
– Spring框架中,Resource接口,资源访问策略
– javax.servlet.http.HttpServlet#service()
解释器模式(Interpreter)
描述如何为语言定义一个文法,如何解析。主要用于使用面向对象语言开发的编译器和解释器设计。当我们需要开发一种新的语言时, 可以考虑使用解释器模式。
尽量不要使用解释器模式,后期维护会有很大麻烦。在项目中,可以使用Jruby,Groovy、java的js引擎来替代解释器的作用,弥补java语言的不足。
-
应用场景
– EL表达式式的处理
– 正则表达式解释器
– SQL语法的解释器
– 数学表达式解析器(现成的工具包:Math Expression String Parser、Expression4J等)!