设计模式
为什么要使用设计模式
- 写出优雅的代码
- 更好的重构项目
- 经典框架都在用设计模式解决问题
- spring 中使用到的设计模式
- 工厂模式 BeanFactory
- 装饰者模式 BeanWrapper
- 代理模式 aopProxy
- 单例模式 applicationContext
- 委派模式 DispatcherServlet
- 策略模式 HandlerMapping
- 适配者模式 HandlerApdapter
- 模板方法模式 JdbcTemplate
- 观察者模式 ContextLoadderListener
…
- spring 中使用到的设计模式
设计模式7原则
-
开闭原则(Open-Closed Principle, OCP)是指一个软件实体如类、模块和函数应该对 扩展开放,对修改关闭。所谓的开闭,也正是对扩展和修改两个行为的一个原则。强调 的是用抽象构建框架,用实现扩展细节。可以提高软件系统的可复用性及可维护性。开 闭原则,是面向对象设计中最基础的设计原则。
-
单一职责(Simple Responsibility Pinciple,SRP)是指不要存在多于一个导致类变更 的原因
-
依赖倒置原则(Dependence Inversion Principle,DIP)是指设计代码结构时,高层模 块不应该依赖底层模块,二者都应该依赖其抽象。抽象不应该依赖细节;细节应该依赖 抽象。通过依赖倒置,可以减少类与类之间的耦合性,提高系统的稳定性,提高代码的 可读性和可维护性,并能够降低修改程序所造成的风险。
-
接口隔离原则(Interface Segregation Principle, ISP)是指用多个专门的接口,而不使 用单一的总接口,客户端不应该依赖它不需要的接口。这个原则指导我们在设计接口时 应当注意一下几点:
- 一个类对一类的依赖应该建立在最小的接口之上。
- 建立单一接口,不要建立庞大臃肿的接口。
- 尽量细化接口,接口中的方法尽量少(不是越少越好,一定要适度)。 接口隔离原则符合我们常说的高内聚低耦合的设计思想,从而使得类具有很好的可读性、 可扩展性和可维护性。我们在设计接口的时候,要多花时间去思考,要考虑业务模型, 包括以后有可能发生变更的地方还要做一些预判。
-
迪米特原则(Law of Demeter LoD)是指一个对象应该对其他对象保持最少的了解,又 叫最少知道原则(Least Knowledge Principle,LKP),尽量降低类与类之间的耦合。迪 米特原则主要强调只和朋友交流,不和陌生人说话。出现在成员变量、方法的输入、输 出参数中的类都可以称之为成员朋友类,而出现在方法体内部的类不属于朋友类。
-
里氏替换原则(Liskov Substitution Principle,LSP)是指如果对每一个类型为 T1 的对 象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都替换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。 定义看上去还是比较抽象,我们重新理解一下,可以理解为一个软件实体如果适用一个 父类的话,那一定是适用于其子类,所有引用父类的地方必须能透明地使用其子类的对 象,子类对象能够替换父类对象,而程序逻辑不变。根据这个理解,我们总结一下: 引申含义:子类可以扩展父类的功能,但不能改变父类原有的功能。
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类中可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类 方法的输入参数更宽松。
- 当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即 方法的输出/返回值)要比父类更严格或相等。
-
合成复用原则(Composite/Aggregate Reuse Principle,CARP)是指尽量使用对象组 合(has-a)/聚合(contanis-a),而不是继承关系达到软件复用的目的。可以使系统更加灵 活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少
spring 中使用到的模块 涉及到的模式
- spring ioc 工厂、单例、装饰者
- spring aop 代理、观察者
- spring mvc 委派、适配器
- spring jdbc 模板方法
工厂模式
-
一、简单工厂模式 (Simple Factory Pattern)
- 介绍:简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例,但它不属于 GOF,23 种设计模式
- 使用场景
- 工厂类负责创建的对象较少
- 客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心
- 简单工厂的忧点
- 只需传入一个正确的参数,就可以获取你所需要的对象 无须知道其创建的细节。
- 简单工厂的缺点
- 工厂类职责过重,增加新的产品需要修改工厂类逻辑,违背开闭原则
- 不易于扩张过于复杂的产品结构
代码如下
public interface ICourse {
/** 录制视频 */
public void record();
}
public class JavaCourse implements ICourse {
public void record() {
System.out.println("录制 Java 课程");
}
public class PythonCourse implements ICourse {
public void record() {
System.out.println("录制 python 课程");
}
public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
ICourse course = factory.create("package.JavaCourse");
course.record();
}
//调用
public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
ICourse course = factory.create(JavaCourse.class); course.record();
}
// Java中涉及 请看
Calendar\createCalendar()
LoggerFactory\getLogger()
-
二、工厂方法模式 (Fatory Method Pattern
- 介绍:工厂方法模式(Fatory Method Pattern)是指定义一个创建对 象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方 法让类的实例化推迟到子类中进行。
属于创建型设计模式。 - 使用场景
- 创建对象需要大量重复的代码。
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
- 一个类通过其子类来指定创建哪个对象
- 优点
- 用户只需关心所需产品对应的工厂,无须关心创建细节
- 加入新产品符合开闭原则,提高了系统的可扩展性
- 缺点
- 类的个数容易过多,增加了代码结构的复杂度。
- 增加了系统的抽象性和理解难度
- 介绍:工厂方法模式(Fatory Method Pattern)是指定义一个创建对 象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方 法让类的实例化推迟到子类中进行。
public interface ICourse {
/** 录制视频 */
public void record();
}
public class JavaCourseFactory implements ICourseFactory {
public ICourse create() {
return new JavaCourse();
}
}
public class PythonCourseFactory implements ICourseFactory {
public ICourse create() {
return new PythonCourse();
}
}
public static void main(String[] args) {
ICourseFactory factory = new PythonCourseFactory();
ICourse course = factory.create();
course.record();
factory = new JavaCourseFactory();
course = factory.create(); course.record();
}
// Java中涉及 请看
LoggerFactory
-
三、抽象工厂模式(Abastract Factory Pattern)
- 介绍:抽象工厂模式(Abastract Factory Pattern)是指提供一个创建 一系列相关或相互依赖对象的接口,无须指定他们具体的类
属于创建型设计模式。 - 使用场景
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对 象需要大量重复的代码。
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使客 户端不依赖于具体实现。
- 优点
- 具体产品在应用层代码隔离,无须关心创建细节
- 将一个系列的产品族统一到一起创建
- 缺点
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难, 需要修改抽象工厂的接口
- 增加了系统的抽象性和理解难度
- 违背开闭原则
- 介绍:抽象工厂模式(Abastract Factory Pattern)是指提供一个创建 一系列相关或相互依赖对象的接口,无须指定他们具体的类
/**
* 抽象工厂是用户的主入口
* 在Spring中应用得最为广泛的一种设计模式
* 易于扩展
*/
public interface CourseFactory {
INote createNote();
IVideo createVideo();
}
public interface INote {
void edit();
}
public interface IVideo {
void record();
}
public class JavaCourseFactory implements CourseFactory {
public INote createNote() {
return new JavaNote();
}
public IVideo createVideo() {
return new JavaVideo();
}
}
public class JavaNote implements INote {
public void edit() {
System.out.println("编写Java笔记");
}
}
public class JavaVideo implements IVideo {
public void record() {
System.out.println("录制Java视频");
}
}
//python
.......
public class AbstractFactoryTest {
public static void main(String[] args) {
JavaCourseFactory factory = new JavaCourseFactory();
factory.createNote().edit();
factory.createVideo().record();
}
}
简单工厂、工厂方法和抽象工厂的区别
-
小结
- 工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
- 使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。
- 工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。
-
区别
- 简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
- 工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
- 抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)