Spring中的各大模块使用的设计模式:
Spring IOC 工厂,单例,装饰器
Spring AOP 代理,观察者
Spring MVC 委派,适配器
Spring JDBC 模板方法
工厂模式相关介绍:
工厂模式的概念:
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
意图:
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
应用实例:
1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
2、Hibernate 换数据库只需换方言和驱动就可以。
优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景:
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
三种工厂模式介绍以及实现:
第一种简单工厂模式(Simple Factory Pattern)
是指由一个工厂对象决定创建出那种产品的实例。它属于创建型模式,但它不属于GOF,23中设计模式。
下面通过三种方式,逐层深入的方式带你了解简单工厂模式。
案例背景:开设的培训班,有java,有Python,大数据,人工智能等课程。
方式一:通过传不同课程参数创建课程类,并调用对应的方法。
首先先创建一个课程接口ICourse,后面再创建一个java实现,大数据实现。
/**
* Created by lijianfang on 2021/9/19.
*/
public interface ICourse {
public void record();
}
在分别创建java课程,大数据课程,python课程等
/**
* Created by lijianfang on 2021/9/19.
*/
public class BigDataCourse implements ICourse {
public void record() {
System.out.printf("正在学习大数据课程");
}
}
/**
* Created by lijianfang on 2021/9/19.
*/
public class JavaICourse implements ICourse{
public void record() {
System.out.println("正在学习java课程");
}
}
创建工厂类,使用参数进行创建。传不同的参数创建不同的课程。
package com.packer.partten.factory;
/**
* Created by lijianfang on 2021/9/20.
*/
public class CourseFactory {
/**
* <p>
* 创建工厂方式一
* </p>
* @param courseName
* @return
*/
public ICourse createCourseOne(String courseName){
if("java".equals(courseName)){
return new JavaICourse();
}else if("python".equals(courseName)){
return new PythonCourse();
}else {
return null;
}
}
}
后面创建测试类,直接在主方法中传参数
/**
* Created by lijianfang on 2021/9/19.
*/
public class SimlpleFactoryTest {
public static void main(String[] args) {
CourseFactory factory = new CourseFactory();
ICourse javaCourse = factory.createCourseOne("java");
javaCourse.record();
}
}
测试结果:
正在学习java课程
Process finished with exit code 0
方式二:通过类的包名来创建对应的课程类,并调用方法。
工厂CourseFactory.java 类中添加如下方法:
/**
* 通过路径名创建
* @param className
* @return
*/
public ICourse createCourseTwo(String className){
try{
if(!(null==className||"".equals(className))){
return (ICourse) Class.forName(className).newInstance();
}
}catch (Exception e){
System.out.println("className = [" + className + "]");
}
return null;
}
测试类中如下调用SimlpleFactoryTest.java中如下调用:
ICourse aCourse = factory.createCourseTwo("com.packer.partten.factory.PythonCourse");
aCourse.record();
测试结果如下:
正在学习python课程
Process finished with exit code 0
方式三:通过类名创建对应的课程类,并调用方法。
工厂CourseFactory.java 类中添加如下方法:
/**
* 通过类创建
* @param clzss
* @return
*/
public ICourse createCourseThree(Class clzss){
try{
if(null!=clzss){
return (ICourse) clzss.newInstance();
}
}catch (Exception e){
System.out.println("clzss = [" + clzss + "]");
}
return null;
}
测试类中如下调用SimlpleFactoryTest.java中如下调用:
ICourse bCourse = factory.createCourseThree(BigDataCourse.class);
bCourse.record();
测试结果如下:
正在学习大数据课程
Process finished with exit code 0
简单工厂模式的适用场景:
1.工厂类负责创建的对象比较少。
2.客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。
3.工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背了开闭原则
4.不易于扩展过于复杂的产品解构
第二种工厂方法模式(Factory Method Pattern)
是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。属于创建型设计模式。
接下来通过代码进行实例演示:
创建课程工厂类
package com.packer.partten.factory.factorymethod;
import com.packer.partten.factory.simplefactory.ICourse;
/**
* Created by lijianfang on 2021/9/20.
*/
public interface ICourseFactory {
public ICourse create();
}
创建java课程工厂
package com.packer.partten.factory.factorymethod;
import com.packer.partten.factory.simplefactory.ICourse;
import com.packer.partten.factory.simplefactory.JavaICourse;
/**
* Created by lijianfang on 2021/9/20.
*/
public class JavaCourseFactory implements ICourseFactory{
public ICourse create() {
return new JavaICourse();
}
}
创建python课程工厂
package com.packer.partten.factory.factorymethod;
import com.packer.partten.factory.simplefactory.ICourse;
import com.packer.partten.factory.simplefactory.PythonCourse;
/**
* Created by lijianfang on 2021/9/20.
*/
public class PythonCourseFactory implements ICourseFactory {
public ICourse create() {
return new PythonCourse();
}
}
创建工厂方法测试类
package com.packer.partten.factory.factorymethod;
import com.packer.partten.factory.simplefactory.ICourse;
/**
* Created by lijianfang on 2021/9/20.
*/
public class MethodFactoryTest {
public static void main(String[] args) {
ICourseFactory factory = new PythonCourseFactory();
ICourse pythonCourse = factory.create();
pythonCourse.record();
}
}
测试结果如下:
正在学习python课程
Process finished with exit code 0
适用场景:
1.创建对象需要大量重复代码。
2.客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。
3.一个类通过其子类来指定创建那个对象。
优点:
1.用户只需要关心所需产品对应的工厂,无需关心创建细节。
2.加入新产品符合开闭原则,提高了系统的可扩展性。
缺点:
1.类的个数容易过多,增加了代码解构的复杂度
2.增加了系统的抽象性和理解难度。
第三种抽象工厂模式(Abstract Factory Pattern)
是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。属于创建型设计模式。
同一个课程中有笔记,有视频录播,有直播。同一接口中必须实现三种。代码具体如下
创建ICourseFactory.java 工厂接口,包含录播课程,笔记,视频直播以公共的接口方式提给使用方。
package com.packer.partten.factory.abstactfactory;
import com.packer.partten.factory.simplefactory.ICourse;
/**
* Created by lijianfang on 2021/9/20.
*/
public interface ICourseFactory {
ICourse createCourse();
INote createNote();
IVideo createVideo();
}
创建单个java课程工厂javaCourseFactory.java
package com.packer.partten.factory.abstactfactory;
import com.packer.partten.factory.simplefactory.ICourse;
import com.packer.partten.factory.simplefactory.JavaICourse;
/**
* Created by lijianfang on 2021/9/20.
*/
public class JavaCourseFactory implements ICourseFactory{
public ICourse createCourse() {
return new JavaICourse();
}
public INote createNote() {
return new JavaINote();
}
public IVideo createVideo() {
return new JavaVideo();
}
}
创建笔记课程类以及相应的接口
package com.packer.partten.factory.abstactfactory;
/**
* Created by lijianfang on 2021/9/20.
*/
public interface INote {
public void note();
}
package com.packer.partten.factory.abstactfactory;
/**
* Created by lijianfang on 2021/9/19.
*/
public class JavaINote implements INote {
public void note() {
System.out.println("正在进行java笔记");
}
}
创建视频录播课程类以及相应的接口
package com.packer.partten.factory.abstactfactory;
/**
* Created by lijianfang on 2021/9/20.
*/
public interface IVideo {
public void video();
}
package com.packer.partten.factory.abstactfactory;
/**
* Created by lijianfang on 2021/9/20.
*/
public class JavaVideo implements IVideo{
public void video() {
System.out.println("正在进行视频直播课程");
}
}
创建测试类AbstactFactoryTest.java
package com.packer.partten.factory.abstactfactory;
/**
* Created by lijianfang on 2021/9/20.
*/
public class AbstactFactoryTest {
public static void main(String[] args) {
ICourseFactory factory = new JavaCourseFactory();
factory.createCourse().record();
factory.createNote().note();
factory.createVideo().video();
}
}
测试结果如下:
正在学习java课程
正在进行java笔记
正在进行视频直播课程
Process finished with exit code 0
使用场景:
1.客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。
2.强调一系列相关的产品对象(同一产品族)一起使用创建对象需要大量重复的代码
3.提供一个产品类的库,所有的产品以同样的接口出现,从而是客户端不依赖于具体实现
优点:
1.具体产品在应用层代码隔离,无须关心创建细节
2.将一个系列的产品族统一到一起创建
缺点:
1.规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
2.增加了系统的抽象性和理解难度