Javaweb学习记录(四)分层处理架构-分层解耦

三层架构

程序设计分为下面三层架构,分别为Controller控制层,Service逻辑处理层,Dao数据访问层。这三层各自执行自己所对应的功能,使程序的扩展性和可维护性提高

例如下面我想设计一个分层的程序,实现Controller层,Service层,Dao层。

需求:

1、将本地xml文件中的数据解析,且用其属性值创建相应对象,将对象放入集合中(Dao层)

2、将集合中的对象的部分属性值进行修改,将修改后的集合进行返回(逻辑处理Service层)

3、将处理好的集合使用Result类进行规范返回响应前端的请求(Controller层)

本程序则需要先在Dao层中创建相关接口,再用相关接口实现类实现该接口,并得到相应的对象集合数据,再在Service层中创建相关接口,创建相关接口实现类,在该类中创建Dao层实现类对象,通过调用类里的方法,得到Dao层返回的集合,在Service实现类对象中对该集合进行处理,并返回该集合,最后在Controller层中创建Service层的实现类对象,通过调用里面的方法得到经过数据处理了的集合,再将该集合用Result规范响应前端的请求。具体分布图如下:

Dao层代码:(不包括接口)

package com.itazhang.dao.impl;

import com.itazhang.dao.EmpDao;
import com.itazhang.pojo.Emp;
import com.itazhang.utils.XmlParserUtils;

import java.util.List;

public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //编码并解析emp.xml文件
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        List<Emp> emplist = XmlParserUtils.parse(file, Emp.class);
        return emplist;
    }
}

Service层代码(不包括接口)

package com.itazhang.service.impl;

import com.itazhang.dao.EmpDao;
import com.itazhang.dao.impl.EmpDaoA;
import com.itazhang.pojo.Emp;
import com.itazhang.service.EmpService;

import java.util.List;

public class EmpServiceA implements EmpService {

    private EmpDao empDao = new EmpDaoA();//创建Dao层的实例化对象

    @Override
    public List<Emp> empService() {
        List<Emp> emplist = empDao.listEmp();//通过实例化对象获取到Dao层数据处理之后的返回值
        emplist.stream().forEach(emp -> {
            //处理性别返回
            String gender = emp.getGender();
            if("1".equals(gender)){
                emp.setGender("男");
            }else{
                emp.setGender("女");
            }

            String job = emp.getJob();
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("就业制导");
            }

        });
        return emplist;
    }
}

Controller层代码

package com.itazhang.controller;

import com.itazhang.dao.impl.EmpDaoA;
import com.itazhang.pojo.Emp;
import com.itazhang.pojo.Result;
import com.itazhang.service.EmpService;
import com.itazhang.service.impl.EmpServiceA;
import com.itazhang.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class EmpController {
    //创建Service层接口实例化对象
    private EmpService emps = new EmpServiceA();
    @RequestMapping("/listEmp")
    public Result list(){

        List<Emp> emplist = emps.empService();

        //响应数据
        return Result.success(emplist);
    }
}

分层解耦思想:

如果一个程序的不同层之间出现耦合,也就是例如在上例中Service层如果要进行数据的逻辑处理的话必须new一个Dao层的对象,通过调用该对象的方法来获取到需要进行逻辑处理的数据,这样程序之间存在的一定联系就是耦合,这种情况会存在许多缺点,例如如果我想要在Service层中去修改需要处理的数据对象,那么必须修改创建的Dao层的对象从而获取到新的数据。这时候分层解耦思想就能被很好的应用,将所有的对象创建都交给外部的容器而不是各个层,如果哪个层需要其他层的对象来实现相关功能,直接由容器创建并把该对象交给他,这样的话就是每层与容器关联而不是层与层互相关联,这时只要每层想要修改本层所使用的数据,只需要重新从容器中获取相应层的对象调用方法就行,而不用在本层中去修改相应层创建的对象。

IOC 控制反转与DI依赖注入的实现

在实际开发中,因为可以快速区分Service层Dao层和Controller层,所以一般使用

Service层对应的@Service注解,Controller层使用的@Controller注解,Dao层对应的@Repository注解来替代@Component注解,@Component注解一般是一些不属于这些层但也需要被IOC容器管理的类进行使用。

在springboot项目中主要通过@Component注解实现控制反转,使用@Autowired实现依赖注入,将需要交给容器管理的类用@Component注解标记表示将该类的创建交给容器管理,再到需要创建该类的其他类里只写创建接口实例化对象但不具体表面创建哪个实例化的对象,并将该创建语句前加上@Autowired注解,这样容器就会根据前面创建接口实例化对象的语句自动分配需要创建的bean对象,例如上例

Service层需要Dao层的数据:那么就将Dao层加上@Component注解,将Dao层的创建交给容器管理,Dao层代码实现如下:

package com.itazhang.dao.impl;

import com.itazhang.dao.EmpDao;
import com.itazhang.pojo.Emp;
import com.itazhang.utils.XmlParserUtils;
import org.springframework.stereotype.Component;

import java.util.List;
@Component
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //编码并解析emp.xml文件
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        List<Emp> emplist = XmlParserUtils.parse(file, Emp.class);
        return emplist;
    }
}

Service层需要创建Dao层的实例化对象,而Controller层也需要创建Servicer层的对象,那么就将Service层的实例化类加上@Component注解,表示将Service层的类创建权交给容器。给Service层实例类里创建的Dao层对象加上@Autowired注解,表示创建Dao层接口的实例化对象时,容器自动注入相关的bean对象,具体代码实现如下:

package com.itazhang.service.impl;

import com.itazhang.dao.EmpDao;
import com.itazhang.dao.impl.EmpDaoA;
import com.itazhang.pojo.Emp;
import com.itazhang.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
@Component
public class EmpServiceA implements EmpService {
    @Autowired
    private EmpDao empDao ;//创建Dao层的实例化对象

    @Override
    public List<Emp> empService() {
        List<Emp> emplist = empDao.listEmp();//通过实例化对象获取到Dao层数据处理之后的返回值
        emplist.stream().forEach(emp -> {
            //处理性别返回
            String gender = emp.getGender();
            if("1".equals(gender)){
                emp.setGender("男");
            }else{
                emp.setGender("女");
            }

            String job = emp.getJob();
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("就业制导");
            }

        });
        return emplist;
    }
}

Controller层则是需要实现接收和响应前端发送来的请求所以需要在类上添加@RestController注解,使该类实现对前端的接收请求和响应功能,而响应的数据来源于Service层,所以创建Service接口的实例化对象的代码前需要添加@AutoWired注解,表示需要创建Service层的实现类的时候将自动注入bean对象,具体代码实现如下 :

package com.itazhang.controller;

import com.itazhang.pojo.Emp;
import com.itazhang.pojo.Result;
import com.itazhang.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class EmpController {
    //创建Service层接口实例化对象
    @Autowired
    private EmpService emps;
    @RequestMapping("/listEmp")
    public Result list(){

        List<Emp> emplist = emps.empService();

        //响应数据
        return Result.success(emplist);
    }
}

而这就会实现减少层之间的耦合性,例如之前的Service层实现类是ServiceDemo1,我要求新添加一种数据逻辑也就是新创建了一个Service层的实现类ServiceDemo2,我需要将该实现类的逻辑添加到项目中,我只需要删除之前的ServiceDemo1的@Component注解,在现在的ServiceDemo2上添加@Component注解,相当于将现在的Service层实现类的对象创建交给IOC容器管理,这样的话,后面创建的Service层的实例化对象就会是ServiceDemo2的对象,我要将Service层数据处理逻辑改变的需求就得以实现。

如果同类型的bean出现多个那么用以下注解进行解决

@Resource注解是通过bean的名称注解,相当于在注解时我们手动的为他表示需要注入哪个名称的bean,而@Autowired就是自动注解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值