Spring IOC思想分析

IOC思想

IOC,Inversion of Control,控制反转。它是一种思想,重点在于理解它,转变自己的思想。本文的核心在于通过一个实际例子来理解控制反转的思想。

1.例子介绍

一般开发一个业务采用的是三层架构,即表示层(UI层)、业务逻辑层(服务层)、数据访问层(DAL)。这里主要关注服务层和数据访问层。

总的功能就是说:服务层想要获取用户信息,进行某种操作(比如验证),会调用数据访问层的对象来实现

2.传统方式实现

2.1 实现方式

传统方式一般采取接口加实现类的方式。

对于服务层:用Service接口和Service1Impl实现类来表示。

对于数据访问层用Dao接口(Data Access Object)和Dao1Impl实现类来表示。(Dao,Data Access Object)

2.2 在IDEA中操作步骤

  第一步:创建maven文件
  第二步:为pom.xml配置文件添加依赖,导入MVC,即
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.1.7</version>
</dependency>
  第三步:等待导入完成,完成结果参考如下

  第四步:开始创建Java文件

主要是创建两个接口和两个实现类。最后的UserService1Impl实现类如下:

public class UserService1Impl implements UserService {
    private Dao userDao=new Dao1Impl();
    public void getUser() {
        userDao.getUser();
    }
}

注意:要导入相关包。

  第五步:进行测试

创建test文件夹中创建MyTest.java文件,参考代码如下

public class MyTest {
    public static void main(String[] args) {
       //用户直接接触表示层,服务请求传到服务层
        UserService userService = new UserService1Impl();
        userService.getUser();
    }
}

运行结果:

  注意

这里用到了面向接口编程的设计模式哦,他的优点在于便于更换不同的实现类(针对于服务层的变化)。具体来说,假定现在要切换到另一个实现类 AdvancedUserServiceImpl,则只需修改实例化的部分:

public class MyTest {
    public static void main(String[] args) {
        // 切换到新的实现类
        UserService userService = new AdvancedUserServiceImpl();
        userService.getUser();
    }
}

public class AdvancedUserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();

    @Override
    public void getUser() {
        System.out.println("Advanced user service is getting user data...");
        userDao.getUser();
    }
}

3.结合IOC思想的方式实现

3.1 传统方式的分析

必须假定现实需求是不断变化的,因此数据层的接口和实现类可能需要很多种,比如不同数据库(mysql,oracal),不同功能(查询,删除,替换)等。会发现,需求一变,数据层代码增加,而服务层由于和数据层强耦合(个人理解为一一对应的联系起来),服务层代码也增加,一旦设计的接口有成千上百个咋办?这种设计思想是不好的。

比如我按传统方式,就需要新建如下的文件:

3.2 set方法分析

传统方式产生弊端的根源在于服务层和数据层的强耦合,而强耦合根源在于每次业务实现类都要new一个相应的数据层实现类

所以根源就在这个new关键字上,更进一步地说:

如果直接在业务代码的设计地方来实例化对象,就一定会强耦合——就是说实例化对象的控制权在核心代码设计的地方,就一定会发生强耦合。

如何解决这个问题?关键就在于把实例化对象的控制权转交出去,一个比较好的方法就是set方法,他将实例化对象的控制权转交给了测试端(可以认为是一个假想的用户)。

3.3 set方法实现

要想办法不要主动创建对象,只是接受客户端是实例化的对象。参考如下代码

public class UserServiceImpl implements UserService {
    private Dao userDao;
    //利用set方法转交实例化对象控制权
    public void setUserDao(Dao userDao) {

        this.userDao = userDao;
    }
    public void getUser() {

        userDao.getUser();
    }
}

测试段代码如下:

public class MyTest {
    public static void main(String[] args) {
       //用户直接接触表示层,服务请求传到服务层
        UserService userService = new UserServiceImpl();
        ((UserServiceImpl)userService).setUserDao(new Dao3Impl());
        userService.getUser();
    }
}

3.4 观察

可以看到,实例化对象的控制权移交了,数据层需求变化,客户端new的对象不同就行啦,不需要改变服务层的对象,大大减少了代码开发量。这就成功实现了IOC(控制反转)。

注意:这儿用了强制类型转换,其语法格式为:(指定类型)对象

4.总结

传统方式,实例化对象的控制权在程序员上;控制反转(比如set注入)后,实例化对象的控制权不在程序员身上了,由此带来的核心业务代码与需求处代码强耦合的问题就没有了,程序员可以更加专注于核心业务!

注意,本文是通过set方法实现控制反转的,正式的spring是用spring 容器来实现的,但思想是相同的。

  • 26
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值