• 01Spring的Ioc思想和依赖注入手段(DI)


    传统方式创建对象的缺陷

    连接MySQL实现登录功能

    控制层UserController

    public class UserController {
        //多态,半面向接口编程
        private UserService userService = new UserServiceImpl();
        public void login(){
            String username = "admin";
            String password = "123456";
            boolean success = userService.login(username, password);
            if (success) {
                // 登录成功
            } else {
                // 登录失败
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    业务层的UserService接口及其实现类UserServiceImpl

    public interface UserService {
        boolean login(String username, String password);
    }
    
    public class UserServiceImpl implements UserService {
    	//多态,面向接口编程
        private UserDao userDao = new UserDaoImplForMySQL();
        public boolean login(String username, String password) {
            User user = userDao.selectByUsernameAndPassword(username, password);
            if (user != null) {
                return true;
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    数据访问层的UserDao接口及其实现类UserDaoImplForMySQL

    public interface UserDao {
        User selectByUsernameAndPassword(String username, String password);
    }
    
    public class UserDaoImplForMySQL implements UserDao {
        public User selectByUsernameAndPassword(String username, String password) {
            // 连接MySQL数据库,根据用户名和密码查询用户信息
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    功能扩展连接Oracle实现登录

    若更换到Oracle数据库上则需要再提供一个UserDaoImplForOracle, 这样就引起了连锁反应,UserServiceImpl类代码需要修改违背了OCP开闭原则

    public class UserDaoImplForOracle implements UserDao {
        public User selectByUsernameAndPassword(String username, String password) {
            // 连接Oracle数据库,根据用户名和密码查询用户信息
            return null;
        }
    }
    
    public class UserServiceImpl implements UserService {
        // 在进行功能扩展的时候修改了源代码, 违背了OCP开闭原则
        // private UserDao userDao = new UserDaoImplForMySQL();
        private UserDao userDao = new UserDaoImplForOracle();
    
        public boolean login(String username, String password) {
            User user = userDao.selectByUsernameAndPassword(username, password);
            if (user != null) {
                return true;
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    软件七大开发原则(为解耦合服务)

    OCP开闭原则

    对外扩展开放修改关闭: 软件开发过程中若在进行功能扩展的时候添加额外的类是没问题的,但因为功能扩展而修改之前运行正常的程序这是不被允许的

    • 因为一旦修改之前运行正常的程序,就会导致项目整体要进行全方位的重新测试(这是相当麻烦的过程)

    传统方式的MVC架构,上层是依赖下层的代码之间的耦合度太高, 这样会导致只要下面改动上面必然也需要改,所谓牵一发而动全身
    在这里插入图片描述

    依赖倒置原则DIP

    依赖倒置原则(Dependence Inversion Principle): 就是倡导面向抽象编程,完全面向接口编程,不要面向具体编程

    • 上层不再依赖下层,即下面改动了上面的代码不会受到牵连 , 这样可以大大降低程序的耦合度,耦合度低了扩展力就强了,同时代码复用性也会增强

    半面向接口编程: 对象的创建和属性的赋值都是手动, 使用到了具体的接口实现类

    public class UserServiceImpl implements UserService {
        //private UserDao userDao = new UserDaoImplForMySQL();
        private UserDao userDao = new UserDaoImplForOracle();
        public boolean login(String username, String password) {
            User user = userDao.selectByUsernameAndPassword(username, password);
            if (user != null) {
                return true;
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    完全面向接口编程:对象的创建是自动的, 属性也是自动赋值的, 但是在执行的时候需要解决空指针异常的问题

    • 第一个问题:谁来负责对象的创建【new UserDaoImplForOracle() 或者 new UserDaoImplForMySQL()】
    • 第二个问题:谁来负责把创建的对象赋到这个属性上【把上面创建的对象赋给userDao属性】
    public class UserServiceImpl implements UserService {
        //private UserDao userDao = new UserDaoImplForMySQL();
        //private UserDao userDao = new UserDaoIm   plForOracle();
        private UserDao userDao;
        public boolean login(String username, String password) {
            User user = userDao.selectByUsernameAndPassword(username, password);
            if (user != null) {
                return true;
            }
            return false;
        }
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    控制反转IoC思想

    控制反转(Inversion of Control)是面向对象编程中的一种设计思想或一种新型的设计模式(由于理论和时间成熟相对较晚,没有被纳入GoF23种设计模式范围内)

    • 当程序既违背OCP又违背DIP时, 可以采用“控制反转”这种编程思想来解决问题 , 可以用来降低代码之间的耦合度
    • 控制是控制资源的获取方式是主动还是被动 , 反转是将对象的创建权交出去,将对象和对象之间关系的维护权交出去,由第三方容器来负责创建与维护

    依赖注入手段(DI)

    依赖注入是实现控制反转这种思想的一种常用实现手段 , 底层使用的是反射机制给属性赋值

    • 依赖(Dependency):对象和对象之间的关联关系, 如A类中有一个B类型的属性就说明A依赖了B
    • 注入(Injection):一种数据传递行为,如给A对象的B类型的属性赋值 ,让A类型的对象和B类型的对象产生了关系(靠注入的手段来维护A和B之间的关系)
    • Spring通过依赖注入的方式来完成Bean管理(实现Bean对象的创建以及Bean对象中属性的赋值或者叫做Bean对象之间关系的维护)

    依赖注入常见的实现方式包括两种

    • set注入(执行set方法给属性赋值)
    • 构造方法注入(执行构造方法给属性赋值)
  • 相关阅读:
    1s 创建100G文件,最快的方法是?
    【Linux】项目自动化构建工具 - make/Makefile
    计算机毕业设计Java校园网络维修系统(源码+系统+mysql数据库+Lw文档)
    【C++】Linux下如何查看opencv的版本
    用 HTTP 提交数据,基本就这 5 种方式
    计算机组成原理 new07 真值和机器数 无符号整数 定点整数 定点小数 $\color{red}{Δ}$
    Android : ListView + BaseAdapter-简单应用
    在Mission Planner上校准外置GPS罗盘
    用好JAVA中的函数式接口,轻松从通用代码中剥离掉业务定制逻辑
    Tomcat 部署 war 包
  • 原文地址:https://blog.csdn.net/qq_57005976/article/details/132939452