关于java:动力节点杜聚宾老师Spring6学习笔记1-Spring启示录

浏览以下代码:

package com.powernode.oa.controller;

import com.powernode.oa.service.UserService;
import com.powernode.oa.service.impl.UserServiceImpl;

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 {
            // 登录失败
        }
    }
}


package com.powernode.oa.service.impl;

import com.powernode.oa.bean.User;
import com.powernode.oa.dao.UserDao;
import com.powernode.oa.dao.impl.UserDaoImplForMySQL;
import com.powernode.oa.service.UserService;

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;
    }
}


package com.powernode.oa.dao.impl;

import com.powernode.oa.bean.User;
import com.powernode.oa.dao.UserDao;

public class UserDaoImplForMySQL implements UserDao {
    public User selectByUsernameAndPassword(String username, String password) {
        // 连贯MySQL数据库,依据用户名和明码查问用户信息
        return null;
    }
}

能够看出,UserDaoImplForMySQL中次要是连贯MySQL数据库进行操作。如果更换到Oracle数据库上,则须要再提供一个UserDaoImplForOracle,如下:

package com.powernode.oa.dao.impl;

import com.powernode.oa.bean.User;
import com.powernode.oa.dao.UserDao;

public class UserDaoImplForOracle implements UserDao {
    public User selectByUsernameAndPassword(String username, String password) {
        // 连贯Oracle数据库,依据用户名和明码查问用户信息
        return null;
    }
}

很显著,以上的操作正在进行性能的扩大,增加了一个新的类UserDaoImplForOracle来应酬数据库的变动,这里的变动会引起连锁反应吗?当然会,如果想要切换到Oracle数据库上,UserServiceImpl类代码就须要批改,如下:

package com.powernode.oa.service.impl;

import com.powernode.oa.bean.User;
import com.powernode.oa.dao.UserDao;
import com.powernode.oa.dao.impl.UserDaoImplForOracle;
import com.powernode.oa.service.UserService;

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.1 OCP开闭准则

这样一来就违反了开闭准则OCP。开闭准则是这样说的:在软件开发过程中该当对扩大凋谢,对批改敞开。也就是说,如果在进行性能扩大的时候,增加额定的类是没问题的,但因为性能扩大而批改之前运行失常的程序,这是禁忌的,不被容许的。因为一旦批改之前运行失常的程序,就会导致我的项目整体要进行全方位的从新测试。这是相当麻烦的过程。导致以上问题的次要起因是:代码和代码之间的耦合度太高。如下图所示:

能够很显著的看出,下层是依赖上层的。UserController依赖UserServiceImpl,而UserServiceImpl依赖UserDaoImplForMySQL,这样就会导致上面只有改变,下面必然会受株连(跟着也会改),所谓牵一发而动全身。这样也就同时违反了另一个开发准则:依赖倒置准则。

1.2 依赖倒置准则DIP

依赖倒置准则(Dependence Inversion Principle),简称DIP,次要提倡面向形象编程,面向接口编程,不要面向具体编程,让下层不再依赖上层,上面改变了,下面的代码不会受到牵连。这样能够大大降低程序的耦合度,耦合度低了,扩大力就强了,同时代码复用性也会加强。(软件七大开发准则都是在为解耦合服务)
你可能会说,下面的代码曾经面向接口编程了呀:

的确曾经面向接口编程了,但对象的创立是:new UserDaoImplForOracle()显然并没有齐全面向接口编程,还是应用到了具体的接口实现类。什么叫做齐全面向接口编程?什么叫做完全符合依赖倒置准则呢?请看以下代码:

如果代码是这样编写的,才算是齐全面向接口编程,才合乎依赖倒置准则。那你可能会问,这样userDao是null,在执行的时候就会呈现空指针异样呀。你说的有情理,的确是这样的,所以咱们要解决这个问题。解决空指针异样的问题,其实就是解决两个外围的问题:

  • 第一个问题:谁来负责对象的创立。【也就是说谁来:new UserDaoImplForOracle()/new UserDaoImplForMySQL()】
  • 第二个问题:谁来负责把创立的对象赋到这个属性上。【也就是说谁来把下面创立的对象赋给userDao属性】

如果咱们把以上两个外围问题解决了,就能够做到既合乎OCP开闭准则,又合乎依赖倒置准则。
很荣幸的告诉你:Spring框架能够做到。
在Spring框架中,它能够帮忙咱们new对象,并且它还能够将new进去的对象赋到属性上。换句话说,Spring框架能够帮忙咱们创建对象,并且能够帮忙咱们保护对象和对象之间的关系。比方:

Spring能够new进去UserDaoImplForMySQL对象,也能够new进去UserDaoImplForOracle对象,并且还能够让new进去的dao对象和service对象产生关系(产生关系其实实质上就是给属性赋值)。
很显然,这种形式是将对象的创立权/管理权交出去了,不再应用硬编码的形式了。同时也把对象关系的管理权交出去了,也不再应用硬编码的形式了。像这种把对象的创立权交出去,把对象关系的管理权交出去,被称为管制反转。

1.3 管制反转IoC

管制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计思维,能够用来升高代码之间的耦合度,合乎依赖倒置准则。
管制反转的外围是:将对象的创立权交出去,将对象和对象之间关系的管理权交出去,由第三方容器来负责创立与保护。
管制反转常见的实现形式:依赖注入(Dependency Injection,简称DI)
通常,依赖注入的实现由包含两种形式:

  • set办法注入
  • 构造方法注入

而Spring框架就是一个实现了IoC思维的框架。
IoC能够认为是一种全新的设计模式,然而实践和工夫成熟绝对较晚,并没有蕴含在GoF中。(GoF指的是23种设计模式)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理