1 概念
模式:是一条由三个部分组成的通用规则,表示了一类特定环境、一类问题和一个解决方案间的关系。
软件领域的设计模式的定义:设计模式是对处于特定环境下,经常出现的某类软件开发问题的,一种相对成熟的设计方案。简单来说,就是以后再遇到同类的问题,直接采用相应的解决方案去解决即可
2 几类设计模式的介绍
Ø 单例模式
l 概念:顾名思义,就是特定环境下的某类问题中的一些类都只需一个实例即可满足需求,实例再多没有太大的意义;在实现方案中这些类就只有一个实例,这些类也被称为单例类,这种模式称为单例模式
l 实现:
n 对与spring框架来说,可以在配置bean实例时指定scope=”singleton”;其中如果配置bean时没有指定scope属性,则该bean实例默认是单例
n 不借助spring框架的话
Class Singleton{
//使用一个变量缓存曾经创建的实例
private static Singleton instance;
//private修饰构造器(隐藏构造器)
private singleton(){}
//提供静态方法用于返回singleton实例,保证有且只有一个实例
public static Singleton getInstance(){
if(null == instance){
//创建一个实例并缓存起来
instance = new Singleton();
}
return instance;
}
}
l 优势
n 减少创建Java实例所带来的系统开销
n 便于系统跟踪单个Java实例的生命周期、实例状态等
Ø 简单工厂
l 概念
n 硬编码耦合:A类的方法实现直接调用了B类的类名。
n 高内聚:指一个模块有相关性很强的代码组成,只负责一项任务,也就是单一责任原则。
n 简单工厂有三种角色
工厂角色:负责创建所有实例,提供给如A来调用
抽象产品角色:工厂创建所有实例的父类,负责描述公共接口
具体产品角色:工厂创建的实例如B
l 实现
Spring本身就是一个大的工厂,直接在xml文件按照bean实例配置即可
l 优势
调用者和实例创建过程分离,避免了调用者和实例实现类的硬编码耦合,提高了系统的维护性和可扩展性
l 缺陷
n 当有新的产品类时,工厂类要修改;
n 违反了高内聚单一责任原则。
Ø 工厂方法和抽象工厂
l 概念
工厂方法:
//使用PrinterFactory实现类来创建OutputFactory
OutputFactory of = new PrinterFactory();
//将Output对象传入,创建Computer对象
Computer c = new Computer(of.getOutput());
抽象工厂:
OutputFactory of = OutputFactory.getOutputFactory(“better”);
//将Output对象传入,创建Computer对象
Computer c = new Computer(of.getOutput());
Ø 代理模式
l 概念:当调用者调用某个实例时,其实并不关心是否得到该对象,它只需要一个能提供该功能的的实例即可,此时我们可以返回此对象的代理(proxy),这种模式被称为代理模式。
l 优势:
n 把创建实例推迟到真正需要它时才创建,这样来保证前面程序运行的流畅性,并且减少实例在内存中的存活时间,宏观上节省了系统的开销;
n 在某些情况下,也许程序永远不会调用实例,意味着系统根本无须创建实例,此时使用代理模式可以显著的提高系统运行性能;
n 目标实例不足以满足需求时,需要代理增强实例的功能;
l 实现:
n Java本身提供了Proxy和InvocationHandler,可以实现在运行时声称动态代理的功能
l 示例:
n Hibernate采用的延迟加载:A实体和B实体存在关联关系,Hibernate默认启用延迟加载,当加载A实体时,B并未被加载,A所关联的B实例都是代理对象,只有等到需要访问B实体时,才会去数据库获取B实体对应的数据,大大降低了系统开销
n AOP采用的也是代理模式,包含了实例所有的方法,还在执行目标方法前后添加了一些通用处理
Ø 命令模式
n 概念:某个方法要实现一个功能,功能的大部分步骤都实现了,可能有少量具体步骤无法确定(不值得重写一个类),必须等到执行该方法时才可以确定,此时需要在调用方法时指定具体的处理行为(一般我们认为处理行为是代码块,但是Java不支持代码块作为参数),可以将接口作为方法的参数,在调用方法时传入接口的匿名实现类即可,以上被称为命令模式
n 示例:spring框架的HibernateTemplate的大部分持久化操作(如executeXxx()等方法)
Ø 策略模式
n 概念:定义了一系列的算法,统一封装在一个context(被称为决策者)的类中,有context来选择调用那个算法
n 三个角色:
u 角色者:context,提供一个默认算法,并且可以设置其他的算法
u 抽象策略:提供策略的规范
u 具体策略:实现不同的策略
n 示例
u Hibernate的Dialect类
u Spring的Resource接口
Ø 门面模式Facade
n 概念:一个功能可能会由多个类来实现,直接使用这些类需要记忆大量的相关类信息,此时我们可以功能的实现代码封装到一个方法中,直接调用这个方法来实现此功能即可。
n 示例
u HibernateTemplate是SessionFactory、Session、Query等类的门面,需要进行持久化查询时只需调用HibernateTemplate即可
u JavaEE应用使用业务逻辑组件来封装DAO组件
Ø 桥接模式
n 概念:一种结构型模型,主要应对的是:一个类有两个或多个维度上的变化,只是继承无法实现或者即使实现也会产生大量代码是的设计臃肿,此时可以把变化的部分抽离出来,是变化的部分和主类分离开,将多个维度的变化也分离,通过主类组合不同维度的变化来达到实现功能的目的。
n 示例:
//辣味的牛肉面
AbstractNoodle noodle = newBeefNoodle(new PepperyStyle());
n JavaEE实现跨数据库的功能就应用了桥接模式
Ø 观察者模式
n 概念:定义了对象间的一对多依赖关系,让一个或多个观察者对象观察一个主题对象;当主题对象发生变化时,系统通知所有依赖此主题对象的观察者,使得观察者的状态发生相应的变化
u 被观察者的抽象基类:持有多个观察者对象的引用,JAVA提供了
java.util.Observable,实际开发中不用开发这个角色
u 观察者接口:通常只包括一个抽象方法update(),JAVA提供了
java.util.Observer,实际开发中不用开发这个角色
u 被观察者的实现类:继承Observable
u 观察者的实现类:继承Observer
n 示例:JMS(Java MessageService,Java消息服务)