• Spring01_概述及程序的耦合


    本教程源码请访问:tutorial_demo

    一、什么是Spring

    Spring是分层的Java SE/EE 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了表现层Spring MVC 和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。

    二、Spring的优势

    方便解耦,简化开发
    通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
    AOP编程的支持
    通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
    声明式事务的支持
    可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
    方便程序的测试
    可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
    方便集成各种优秀框架
    Spring可以降低各种框架的使用难度,提供了对各种优秀框架(MyBatis、Hibernate、Hessian、 Quartz等)的直接支持。
    降低JavaEE API的使用难度
    Spring对JavaEE API(如 JDBC、 JavaMail、远程调用等)进行了封装,使这些 API 的使用难度大为降低。

    三、程序的耦合

    3.1、什么是程序的耦合

    耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立性)。 耦合性存在于各个领域,而非软件设计中独有的,但是我们只讨论软件工程中的耦合。
    在软件工程中, 耦合指的就是就是对象之间的依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。 软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。 **划分模块的一个准则就是高内聚低耦合。 **

    我们在开发中,有些依赖关系是必须的,有些依赖关系可以通过优化代码来解除。

    案例一:

    /* 示例代码
    *	账户的业务层实现类
    */
    public class AccountServiceImpl impalements IAccountDao {
        private IAccountDao accountDao = new AccountDaoImpl();
    }
    

    业务层调用持久层,并且此时业务层在依赖持久层的接口和实现类。如果此时没有持久层实现类,编译将不能通过。这种编译期依赖关系,应该在我们开发中杜绝。 我们需要优化代码解决 。

    案例二:

    public static void main(String[] args) throws Exception {
    	//1.注册驱动
    	//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    	Class.forName(driverName);//driverName是读取配置文件获取的字符串
    	//2.获取连接
    	//3.获取预处理 sql 语句对象
    	//4.获取结果集
    	//5.遍历结果集
    }
    

    早期我们的JDBC操作,注册驱动时,我们为什么不使用DriverManager的register方法,而是采用Class.forName的方式?我们的类依赖了数据库的具体驱动类(MySQL),如果这时候更换了数据库品牌(比如 Oracle),需要修改源码来重新数据库驱动。这显然不是我们想要的。

    3.2、解决程序耦合的原则

    当是我们讲解 jdbc 时,是通过反射来注册驱动的,代码如下:

    Class.forName(driverName);//driverName是读取配置文件获取的字符串
    

    耦合:程序间的依赖关系。包括类之间的依赖和方法间的依赖。

    解耦:降低程序间的依赖关系。

    实际开发中应该做到:编译期不依赖,运行时依赖。

    解耦的思路

    1. 使用反射来创建对象,而避免使用new关键字;
    2. 通过读取配置文件来获取要创建的对象全限定类名。

    3.3、使用工厂模式解决程序耦合

    在实际开发中,我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建并进行存储。需要用的时候,直接拿来使用。这个读取配置文件,创建和获取三层对象的类就是工厂。具体实现请看下面的代码。

    3.3.1、创建一个普通的Maven工程

    pom.xml配置如下

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.codeaction</groupId>
        <artifactId>factory</artifactId>
        <version>1.0-SNAPSHOT</version>
    </project>
    

    3.3.2、创建各层实现类的配置文件bean.properties

    accountService=org.codeaction.service.impl.AccountServiceImpl
    accountDao=org.codeaction.dao.impl.AccountDaoImpl
    

    3.3.3、创建工厂类

    package org.codeaction.factory;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.*;
    
    /**
     *   通过读取配置文件中配置的内容,反射创建对象
     *   我的配置文件可以是xml也可以是properties
     */
    public class BeanFactory {
        //定义一个Properties对象
        private static Properties props;
        //定义一个Map,用于存放我们要创建的对象。我们把它称之为容器
        private static Map<String, Object> beans;
        //使用静态代码块为Properties对象赋值
        static {
            try {
                //获取properties文件的流对象
                InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
                //实例化对象
                props = new Properties();
                props.load(in);
                //实例化容器
                beans = new HashMap<String, Object>();
                //取出配置文件中所有的Key
                Enumeration<Object> keys = props.keys();
                //遍历枚举
                while (keys.hasMoreElements()) {
                    //取出每个Key
                    String key = keys.nextElement().toString();
                    //根据key获取value
                    String beanName = props.getProperty(key);
                    //反射创建对象
                    Object bean = Class.forName(beanName).newInstance();
                    //把key和value存入容器中
                    beans.put(key, bean);
                }
            } catch (IOException e) {
                throw new ExceptionInInitializerError("初始化错误");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 根据bean的名称获取对象
         * @param beanName
         * @return
         */
        public static Object getBean(String beanName) {
            return beans.get(beanName);
        }
    }
    

    3.3.4、创建持久层接口及其实现类

    持久层接口:

    package org.codeaction.dao;
    
    public interface IAccountDao {
        void saveAccount();
    }
    

    持久层接口的实现类:

    package org.codeaction.dao.impl;
    
    import org.codeaction.dao.IAccountDao;
    
    public class AccountDaoImpl implements IAccountDao {
        //这里只是一个模拟,不要在意实现细节
        @Override
        public void saveAccount() {
            System.out.println("账户保存成功");
        }
    }
    
    

    3.3.5、创建业务层接口及其实现类

    业务层接口:

    package org.codeaction.service;
    
    public interface IAccountService {
        void saveAccount();
    }
    

    业务层接口的实现类:

    package org.codeaction.service.impl;
    
    import org.codeaction.dao.IAccountDao;
    import org.codeaction.factory.BeanFactory;
    import org.codeaction.service.IAccountService;
    
    public class AccountServiceImpl implements IAccountService {
        private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");
    
        @Override
        public void saveAccount() {
            accountDao.saveAccount();
        }
    }
    

    3.3.6、创建视图层

    package org.codeaction.ui;
    
    import org.codeaction.factory.BeanFactory;
    import org.codeaction.service.IAccountService;
    
    public class AccountUI {
        public static void main(String[] args) {
            IAccountService accountService = (IAccountService) BeanFactory.getBean("accountService");
            accountService.saveAccount();
        }
    }
    

    3.3.7、Spring中解决程序的耦合

    在Spring中使用IOC的方式解决程序的耦合,具体内容请见后面的教程。

  • 相关阅读:
    CSS3中各种属性的意思
    Python全栈Day 18部分知识点
    Python全栈Day 17部分知识点
    Python全栈Day 16部分知识点
    Python全栈Day 15部分知识点
    Python全栈Day 14部分知识点
    Python全栈Day 13部分知识点
    Python全栈Day 12部分知识点
    Python全栈Day 11部分知识点
    时间复杂度和空间复杂度
  • 原文地址:https://www.cnblogs.com/codeaction/p/12951853.html
Copyright © 2020-2023  润新知