Spring中使用工厂模式解耦详解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Spring中使用工厂模式解耦详解

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站点击跳转浏览。


解耦 降低程序之间的耦合性


为什么要降低程序之间的耦合性


**原因很简单。当耦合度很高时,在代码维护过程中修改一个地方会涉及到很多地方。如果耦合关系不是澄清修改期间,后果可能是灾难性的,特别是对于有许多变化的项目需求和多人协作开发和维护,修改一个地方会导致模块的错误一直运行稳定,如果是严重的,将导致一个恶性循环,问题永远不能完全解决,开发和测试正与各种各样的问题作斗争。最终会导致项目延迟,降低用户满意度,增加成本。而且也提高了程序的复用性


引入类之间的耦合性


在我们学习jdbc访问数据库时,具体流程是

首先在maven里面导入依赖


<packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>


然后就是jdbc的实现过程:

1.注册驱动

2.获取连接

3.获取操作数据库的预处理对象

4.执行SQL,得到结果集

5.遍历结果集

6.释放资源

具体代码如下:


public class Jdbc {
    public static void main(String[] args) throws  Exception{
        //1.注册驱动
  //  DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","1234");
        //3.获取操作数据库的预处理对象
        PreparedStatement pstm = conn.prepareStatement("select * from account");
        //4.执行SQL,得到结果集
        ResultSet rs = pstm.executeQuery();
        //5.遍历结果集
        while(rs.next()){
            System.out.println(rs.getString("name"));
        }
        //6.释放资源
        rs.close();
        pstm.close();
        conn.close();
    }
}

第一种创建驱动方式


进行分析,上面代码中被注释的那句代码

DriverManager.registerDriver(new com.mysql.jdbc.Driver());

如果把pom里面的依赖注释就相当于没有jar包,然后我们进行编译

则不能编译,会是一个错误,如图所示:


第二种创建驱动方式


Class.forName(“com.mysql.jdbc.Driver”);

这句代码就只依赖于一个字符串而不是一个驱动类。

这样子当jar包不存在时,就是一个异常而不是一个错误。这样子就是避免的类之间的耦合性



但是产生一个新的问题,导致这个字符串在类中写死了如果换成其他数据库的话,就还要改代码,所以我们要通过配置文件来获取要创建的对象全限定类名,然后再用反射来创建对象

所以 解耦的思路:

第一步:使用反射来创建对象,而避免使用new关键字。
第二步:通过读取配置文件来获取要创建的对象全限定类名


实际开发中:

应该做到:编译期不依赖,运行时才依赖。


业务层Service调用持久层Dao时的耦合性


Dao层


userdao层的接口

public interface IUserDao {
    void save();
}

userdao层的实现类


package Dao.IMPL;
import Dao.IUserDao;
public class UserDao implements IUserDao {
    public void save() {
        System.out.println("hello");
    }
}

UserService的接口


package Service;
public interface IUserService {
    void save();
}

UserService的实现类


package Service.IMPL;
import Dao.IMPL.UserDao;
import Service.IUserService;
public class UserService implements IUserService {
    //private将这个对象私有化
    //因为dao是一个接口的实现类  接口是不是实例化的 但是可以创建一个接口的实现类对象
    private IUserDaodao=new UserDao();
    public void save() {
        System.out.println("hello");
    }
}

private IUserDaodao=new UserDao(); 这句代码就是Service层调用Dao层,当我们把UserDao的代码去除之后,程序就出现报错,不能编译成功,说明程序之间的耦合性太强了。


工厂模式解耦合


上面的service层调用dao层的耦合性太强之后我们可以参考之前的jdbc里面的步骤。


第一步:使用反射来创建对象,而避免使用new关键字。
 第二步:通过读取配置文件来获取要创建的对象全限定类名

所以我们可以通过工厂来进行一个解耦

BeanFactory:个创建Bean对象的工厂


什么是Bean


在计算机英语中,有可重用组件的含义,可重用的意思是一个servlet可能有多个service 一个service中可能有多个dao.一个servicc或者一个dao都是一个Bean


第一步:需要一个配置文件来配置我们的service和dao 配置的内容:唯一标识=全限定类名(key=value)


我们创建一个Bean.properties也可以是一个Bean.xml,在这里我们在resources里面创建一个Bean.properties记录里面的全限定类名


UserService=Service.IMPL.UserService
UserDao=Dao.IMPL.UserDao

第二步通过读取配置文件中配置的内容,反射创建对象


package factory;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class BeanFactory {
    //读取配置文件
    //定义一个静态Properties对象
    private static Properties props;
//    //定义一个Map,用于存放我们要创建的对象。我们把它称之为容器
    //多例变单例
    private static Map<String,Object> beans;
    //使用静态代码块为Properties对象赋值
    static {
        try {
            //实例化对象
            props = new Properties();
            //获取properties文件的流对象
            //这个时候不能用new FileInputStream因为这这个时候的相对路肩和绝对路径都不管用
            //we工程部署src没有了   相对路径不能用 绝对路径也不行
            //要用类加载器来进行操作
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            //加载一个流对象
            props.load(in);
//            //实例化容器
            beans = new HashMap<String,Object>();
//            //取出配置文件中所有的Key
            Enumeration keys = props.keys();
//            //遍历枚举
            while (keys.hasMoreElements()){
//                //取出每个Key
                String key = keys.nextElement().toString();
//                //根据key获取value
                String beanPath = props.getProperty(key);
//                //反射创建对象
                Object value = Class.forName(beanPath).newInstance();
//                //把key和value存入容器中
                beans.put(key,value);
            }
        }catch(Exception e){
            //抛出一个初始化错误  后面直接执行不了
            throw new ExceptionInInitializerError("初始化properties失败!");
        }
    }
    /**
     * 根据bean的名称获取对象  用Object类型做返回值
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName){
        return beans.get(beanName);


这样之后,我们再调用dao层时就可以把在BeanFactory里面创建


private IUserDao dao= (IUserDao) BeanFactory.getBean("UserDao");


同样调用service代码也发生变化


IUserService service= (IUserService) BeanFactory.getBean("UserService");


这样之后,再把删除就只报异常,而且如果需要更改代码里面的值,我们就只用更改配置文件里面的代码这样就可以更加快速的进行更改操作。


新创建一个公众号 Rockey小何同学 想相互交流的同学可以关注一下哈! 感谢支持!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
Java 开发者 Spring
Spring Boot 实现解耦和隔离的技术指南
【6月更文挑战第13天】Spring Boot 作为一种流行的 Java 框架,通过其强大的依赖注入和配置管理功能,使得开发者可以轻松实现模块之间的解耦和隔离
69 3
|
5月前
|
XML Java 数据格式
[Spring 基础] 掌握Spring DI,轻松解耦你的应用
[Spring 基础] 掌握Spring DI,轻松解耦你的应用
|
设计模式 Java uml
彻底搞懂Spring状态机原理,实现订单与物流解耦
状态模式的UML类图如下图所示。
284 0
|
设计模式 前端开发 Java
【Spring】工厂模式
【Spring】工厂模式
|
前端开发 JavaScript Java
浅谈Spring的相关概念性问题 IOC DI AOP 工厂模式 单例
浅谈Spring的相关概念性问题 IOC DI AOP 工厂模式 单例
136 0
|
设计模式 Java Spring
java spring设计模式 之 工厂模式
java spring设计模式 之 工厂模式
|
XML 人工智能 Java
Spring中基于xml的IOC解耦
Spring中基于xml的IOC解耦
|
消息中间件 Java Spring
下单流程解耦新方案-你知道Spring事件监听机制吗
下单流程解耦新方案-你知道Spring事件监听机制吗
98 0
|
前端开发 Java Spring
Spring MVC-02循序渐进之解耦控制器和校验器
Spring MVC-02循序渐进之解耦控制器和校验器
75 0
|
Java UED Spring
如何实现业务解耦?spring中事件监听了解一下
耦合这个词在平常的开发工作中应该不陌生,简单理解就是代码中各部分关联度过高。
如何实现业务解耦?spring中事件监听了解一下
下一篇
无影云桌面