• 08-MVC&JavaBean


    MVC 设计模式

    MVC 模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为 3 个基本部分:模型(Model)、视图(View)和控制器(Controller)。

    MVC 可对程序的后期维护和扩展提供了方便,并且使程序某些部分的重用提供了方便。而且 MVC 也使程序简化,更加直观。

    • 控制器 Controller:对请求进行处理,负责请求转发
    • 视图 View:界面设计人员进行图形界面设计
    • 模型 Model:程序编写程序应用的功能(实现算法等等)、数据库管理;

    注意,MVC 不是 Java 的东西,几乎现在所有 B/S 结构的软件都采用了 MVC 设计模式。

    JavaWeb 与 MVC

    Model 1

    version-1

    JSP Model1 是 JavaWeb 早期的模型,它适合小型 Web 项目,开发成本低!Model 1 第一代时期,服务器端只有 JSP 页面,所有的操作都在 JSP 页面中,连访问数据库的 API 也在 JSP 页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。

    version-2

    JSP Model1 第二代有所改进,把业务逻辑的内容放到了 JavaBean 中,而 JSP 页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但还让 JSP 做了过多的工作,JSP 中把视图工作和请求调度(控制器)的工作耦合在一起了。

    Model 2

    JSP Model2 模式已经可以清晰的看到 MVC 完整的结构了。

    • JSP:视图层,用来与用户打交道。负责接收用来的数据,以及显示数据给用户
    • Servlet:控制层,负责找到合适的模型对象来处理业务逻辑,转发到合适的视图
    • JavaBean:模型层,完成具体的业务工作,例如:开启、转账等。

    注意,在 Service 层中不能出现 JavaWeb API,例如 request、response 等。也就是说,Service 层代码是可重用的,甚至可以应用到非 Web 环境中。业务层的每个方法可以理解成一个万能,例如转账业务方法。Service 层依赖 Dao 层,而 Web 层依赖 Service 层!

    MVC 与 三层架构

    摘自:https://www.jianshu.com/p/71ae09665214

    简述

    在软件开发中,MVC 与三层架构这两个专业词汇经常耳闻,同时总有很多人将它们混为一谈,认为三层架构就是指 MVC,给它画上等号,但实际上,这是错误的认知,并不是说它们没有任何关系,而是 MVC 与三层架构不是简单的相等。下面将拿 JavaWeb 开发中的 MVC(SSM框架)与三层架构进行比较,让大家理清两者之间的关系。

    概念

    系统架构

    所谓系统架构是指整个应用系统程序大的结构,常见的系统架构有三层架构与MVC。前面已经说了,三层架构与 MVC 不是简单的相等,它们存在差别,但又联系。现在可以肯定的是,这两种系统架构的出现,都是为了降低系统模块间的耦合度。

    三层架构

    三层架构是指:视图层 View、服务层 Service、持久层 Dao,分别完成不同的功能。

    • View 层:用于接收用户提交请求的代码在这里编写
    • Service 层:系统的业务逻辑主要在这里编写
    • Dao 层:直接操作数据库的代码在这里编写

    为了更好的降低各层间的耦合度,在三层架构程序设计中,采用面向抽象编程。即上层对下层的调用,是通过接口实现的。而下层对上层的真正服务提供者,是下层接口的实现类。服务标准(接口)是相同的,服务提供者(实现类)可以更换。这就实现了层间耦合的降低。

    MVC

    MVC 是指:Model 模型、View 视图、Controller 控件器。

    • View:视图,为用户提供使用界面,与用户直接进行交互
    • Model:模型,承载数据,并对用户提交请求进行计算的模块。其分为两类,一类称为数据承载 Bean,一类称为业务处理 Bean
      • 所谓数据承载 Bean 是指实体类,专门承载业务数据的,如 Student、User 等
      • 而业务处理 Bean 则是指 Service 或 Dao 对象,专门用于处理用户提交请求的
    • Controller:控制器,用于将用户请求转发给相应的 Model 进行处理,并处理 Model 的计算结果向用户提供相应响应

    MVC 架构程序的工作流程是这样的:

    1. 用户通过 View 页面向服务端提出请求,可以是表单请求、超链接请求、AJAX 请求等
    2. 服务端 Controller 控制器接收到请求后对请求进行解析,找到相应的 Model 对用户请求进行处理
    3. Model 处理后,将处理结果再交给 Controller
    4. Controller 在接到处理结果后,根据处理结果找到要作为向客户端发回的响应 View 页面。页面经渲染(数据填充)后,再发送给客户端。

    关系

    MVC 与三层架构的关系

    MVC 与三层架构很相似,但它们并不一样。如果以三层架构为背景,那么 MVC 的三个部分分别对应的是什么?

    • 三层架构中的 View 层简单的说就是跟用户发生直接关系的层,MVC 中的 V 和 C 就是这样的存在,所以 MVC 中的 V 和 C 均属于三层架构的 View 层
    • 同时,我们知道 MVC 中的M(Model)包括了数据承载 Bean 和业务处理 Bean,其中业务处理 Bean 分为 Service 或 Dao 对象,分别对应业务逻辑处理和数据库操作,相应的,它们对应的是三层架构中的 Service 层和 Dao 层
    • 故,它们的关系如下图所示:

    SSM 与 三层架构的关系

    SSM 即 SpringMVC、Spring、Mybatis 三个框架。它们在三层架构中所处的位置是不同的,即它们在三层架构中的功能各不相同,各司其职。

    • SpringMVC:作为 View 层的实现者,完成用户的请求接收功能。SpringMVC 的 Controller 作为整个应用的控制器,完成用户请求的转发及对用户的响应。
    • MyBatis:作为 Dao 层的实现者,完成对数据库的 CRUD 功能。
    • Spring:以整个应用大管家的身份出现。整个应用中所有的 Bean 的生命周期行为,均由 Spring 来管理。即整个应用中所有对象的创建、初始化、销毁,及对象间关联关系的维护,均由 Spring 进行管理。

    JavaBean

    • JavaBean 是一个遵循特定写法的 Java 类,它通常具有如下特点:
      • 这个 Java 类必须具有一个无参的构造函数
      • 属性必须私有化
      • 私有化的属性必须通过 public 类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范
    • JavaBean 在开发中,通常用于封装数据,对于遵循以上写法的 JavaBean 组件,其它程序可以通过反射技术实例化 JavaBean 对象,并且通过反射那些遵守命名规范的方法,从而获知 JavaBean 的属性,进而调用其属性保存数据。
    • JavaBean 的属性
      • JavaBean的属性可以是任意类型,并且一个 JavaBean 可以有多个属性。每个属性通常都需要具有相应的 setter、 getter 方法,setter 方法称为属性修改器,getter 方法称为属性访问器。
      • 属性修改器必须以小写的 set 前缀开始,后跟属性名,且属性名的第一个字母要改为大写,例如, name 属性的修改器名称为 setName,password 属性的修改器名称为 setPassword。
      • 属性访问器通常以小写的 get 前缀开始,后跟属性名,且属性名的第一个字母也要改为大写,例如,name 属性的访问器名称为 getName,password 属性的访问器名称为 getPassword。
      • 一个 JavaBean 的某个属性也可以只有 set 方法或 get 方法,这样的属性通常也称之为只写、只读属性。
    • JavaBean 要实现 Serializable<I>

    软件分层

    • 为什么要分层?
      • 使软件具有结构性,便于开发、维护和管理
      • 将不同功能模块独立,在需要替换某一模块时不需要改动其他模块,方便代码的复用、替换
    • 层与层的耦合
      • 在分层结构中,我们希望将各个功能约束在各自的模块(层)当中的,而当属于某一层的对象、方法“入侵”到了其他层,如将 web 层的 ServletContext 对象传入 service 层,或 service 层调用 Dao 独有的方法,就会导致层与层之间的关系过于“紧密”,当需要修改某一层时不可避免的要修改其他关联的层,这和我们软件分层最初的设想 —— 层与层分离,一个层尽量不依赖其他层存在,当修改一层时无需修改另一层的设想是违背的。
      • 这种“入侵”造成的“紧密”关系就早做层与层之间发生的“耦合”,而去掉这种耦合性的过程就叫做层与层之间“解耦”。利用工厂类可以实现解耦的功能
    • 如何判断一项功能属于哪一层?
      • 此项功能在业务逻辑上更贴近与哪一层,放在哪一层更能较少耦合
      • 此项功能是否必须使用某一层特有的对象
      • 如果放在哪一层都可以,那么放在哪一层更方便技术上的实现,及方便代码的编写和维护

    config.properties

    CustService=cn.edu.nuist.service.impl.CustServiceImpl
    CustDao=cn.edu.nuist.dao.impl.CustDaoImpl
    

    BasicFactory

    public class BasicFactory {
        private BasicFactory() {}
        private static BasicFactory factory = new BasicFactory();
        private static Properties prop = null;
    
        static {
            prop = new Properties();
            try {
            prop.load(new FileReader(BasicFactory.class.getClassLoader()
                    .getResource("config.properties").getPath()));
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    
        public static BasicFactory getFactory() {
            return factory;
        }
    
        // 使用泛型实现层与层之间的解耦
        public <T> T getInstance(Class<T> clazz) {
            String cName = clazz.getSimpleName();
            String cImplName = prop.getProperty(cName);
            try {
                return (T) Class.forName(cImplName).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }
    

    异常的处理

    • 如果一个异常抛给上一层会增加程序的耦合性,请当场解决:如将 XML 解析错误抛给 service 层,那么当换成 MySQLDAO 时,还需要修改 service 去掉 XML 解析异常的处理
    • 如果上一层明确需要此异常进行代码的流转,请抛出:如当查找一个用户信息而用户找不到时,可以抛出一个用户找不到异常,明确要求上一层处理
    • 如果这一层和上一层都能解决尽量在这一层解决掉
    • 如果这一层不能解决,而上一层能解决抛给上一层
    • 如果所有层都不能解决,则应抛出给虚拟机使线程停止,但是如果直接抛出这个异常,则还需要调用者一级一级继续往上抛出最后才能抛给虚拟机,所以还不如在出现异常的位置直接 try-catch 住后转换为 RuntimeException 抛出。如:读取配置文件出错,任何层都不能解决,转为 RuntimeException 抛出,停止线程
  • 相关阅读:
    字王谈M1字形与个人云字库
    想让网站销量爆涨?你离成功只差一个出色的购物车设计
    学习JavaScript很吃力?开发五年经验带你轻松上路!
    摹客—— 自动生成你的颜色规范
    【求职,不求人】2019最全Web设计师面试问题,助你轻松拿下面试
    交易类APP原型设计分享
    全是宝!20款优质高效的在线协作工具任你挑,就是这么强大!
    灵感专题—2019年优秀网页设计作品赏析#4月
    2019年最实用的导航栏设计实践和案例分析全解
    摹客标注:自动标注一键生成,手动标注自由补充
  • 原文地址:https://www.cnblogs.com/liujiaqi1101/p/13388647.html
Copyright © 2020-2023  润新知