Java Web:我对架构中分层的理解暨 Bigfoot Web 框架简介

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据同步 1个月
简介: J2EE 世界充斥着许多概念,如 MVC、Service、DAO 等等,而且这些许多都是“似是而非”的名词。如果不对这些概念进行厘清,恐怕不能全然贯通、明晰整个框架。这就体现了概念其重要性。鄙人希望:一、概念虽然会比较”笼统“,——这是因为概念处于较高层的位置,有涵盖的作用,但应该尽量明晰和收窄定义的范围;二、从概念到某件事物,是”抽象“到”具象“的过程,会形成某个特定”名词“,既然”名词“是特指的,那么应该没有二义性,即没有歧义;三、概念最后能找到真正所对应的具体事物,可以在代码中反映出来的。

J2EE 世界充斥着许多概念,如 MVC、Service、DAO 等等,而且这些许多都是“似是而非”的名词。如果不对这些概念进行厘清,恐怕不能全然贯通、明晰整个框架。这就体现了概念其重要性。鄙人希望:一、概念虽然会比较”笼统“,——这是因为概念处于较高层的位置,有涵盖的作用,但应该尽量明晰和收窄定义的范围;二、从概念到某件事物,是”抽象“到”具象“的过程,会形成某个特定”名词“,既然”名词“是特指的,那么应该没有二义性,即没有歧义;三、概念最后能找到真正所对应的具体事物,可以在代码中反映出来的。凡事须顾名思义,有其名就当有其实;四、理想情况下,一个系统不应存在重复的代码或模块。如果赋予一个事物有一个概念或名词 A,A 具有排他性,不能再使用,但可以包含其所属的 B 事物。即,A 是 A,B 是 B。如果 A 包含 B,那么 A ≠ B。

需要指出的是,本文所讨论的定义对其他框架不一定适用,请不要周延,当前仅限于 Bigfoot 界定概念所用——这也是为了避免争议的提前声明,同时这样也比较简单,点到即止。

基础概念

分层是应对复杂性的必然手段。解决一个个各自的小问题,最终来解决大问题,“分而治之”。

程序三层结构,毋庸置疑。


与数据库打交道的三个方法

以上脑图参考自《三层究竟如何?》

我们比较推崇“半自动 SQL”的方法,既非直接写 SQL,也不是 ORM(也不熟悉 存储过程)。此方面的具体内容,参见前篇文章《浅浅地封装一层 JDBC》

一般 SSH 结构

虽然有经典 SSH 架构摆在面前,但我们并不拘泥于此,同样积极寻找适应项目变化,可重用,方便程序员的架构方法,以适应于“互联网程序架构”而非单单“企业级开发”的架构。

JavaEE 体系架构

JavaEE 体系架构采用传统的 MVC 设计模式,分为 Model、View、Controller 三层,其中:Model 即模型层,定义数据模型和业务逻辑。

为了将数据访问与业务逻辑分离,提高业务精度,降低代码之间的耦合,模型层又细分为 DAO 层与 Service 业务层,DAO 全称为 Data Access Object(数据访问对象),将数据库访问代码封闭起来,MyBatis API 也在此封装,不再出现在其他层或向其他层暴露;业务层是整个系统最核心也最具价值的一层,该层对应用程序的业务逻辑进行封装,务求关注客户需求,在业务处理过程中会访问原始数据或产生新数据,或者需要持久化数据,DAO 层提供的 DAO 类能很好地帮助业务层完成数据处理,业务层本身则侧重于对客户需求的理解和业务规则的适应,自然也包括大部分的计算。

总体说来,DAO 不处理业务逻辑,只做与存取数据有关的获取原始数据或持久化数据等操作,为业务层提供辅助。

View 即视图层,为最终用户提供一个友好的交互界面,用户可以查看请求结果,也可以通过表单等交互手段实现数据录入。

Controller 层即控制器,他是 Model 与 View的桥梁,将二者很好的衔接,通过 View 接收用户数据,Controller 将数据传输给Model,Model 对数据进行处理;或者 Model 读取数据后,Controller 将数据传递给 View,View 向用户展示数据。一来一往,Controller 成了 Model 与 View 之间的快乐使者。具体来说,Controller 负责数据验证,跳转逻辑,赋值/取值。这里会出现 Request/Response 对象——但将 Request/Response 对象放到其他层就不合适了,举个反例,如果在 Service 层出现 Request/Response 对象那么有必要进行重构修正了。

  • 从调用关系上看,左为高层,右为低层,下为高层,上为低层,高层可以调用低层,但低层不能调用高层,层与层之间的调用是单向的。
  • 从数据传输上看,数据可以从视图层传输到 DAO 进而保存到数据库,也可以从数据库中读取数据进行处理或者显示,所以数据的传输是双向的。
  • 从技术实现上看,视图层使用 HTML/JSP 组件实现,控制器使用 Servlet 或 Action 组件实现,模型层使用 JavaBean 组件或 EJB 技术实现。

MyBatis 封装在 DAO 层,负责数据访问操作;Spring MVC 充当控制器角色,对用户数据进行合法性检验和类型转换,为视图层提供标签简化页面显示,提供国际化支持等等;Spring是应用程序的管家,DAO、Service(业务)、Action 等对象由 Spring 创建并维护各对象之间关系,同时提供声明式事务管理,简化事务编程。

MVC 结构

可维护的结构



MVC 是个大领纲,不同的框架对 MVC 的理解和实践都不尽相同,有时候甚至很难一一对号入座,也有许多衍生分支的版本。实际上,MVC 是一种模式,模式不是公式,所以除了必要的条件限定之外,就没有一定的条条框框。

注意,前面说到的三层架构 ≠ MVC。

除了经典的 JSP + Bean + Servlet 架构外,还有一种更为简单的 JSP + Bean 模式。两者区别在于处理的主控部分不同。前者利用 Servlet 作为主控部分;后者利用 JSP 作为主控部分,将用户的请求、Bean 和事件响应有效的连接起来。

我比较倾向于 JSP + Bean 模式。该模式工作原理是:当 HTTP 发出请求时,JSP 接收请求并访问 Bean,当需要访问数据库或者服务器时,则通过  Bean 做相应处理。Bean 将处理的结果返回 JSP,JSP 生成动态 html 将结果传送到浏览器并显示,用户得到交互结果。JSP 作为视图,同时也有部分控制器的功能, Bean 组件作为模型和控制器组件。

这样的好处是首先不用配置 Servlet,一个 JSP 即是 Servlet(请求路径多起来维护麻烦),其次是 JSP 以显示为中心,它为 Web 前端开发提供了更方便的开发。再者是仍然可以做到显示和内容分离,显示和业务逻辑开发可以分开同时进行,实际上并不会在 JSP 嵌入大量 Java 代码,而且显得更简单。

必须提出的是,纯 service 接口的话应该使用 Bean + Servlet 的模式,那是完全排除表示层的考虑。


前端分层,围绕 HTML、CSS、JS 三大模块来处理。


模板技术我主张使用 Tag Files。有关 Tag Files 的更多教程,参见本博客《JSP Tag Files 技术总结》

项目选型

经过反复使用和衡量,决定采用下面的组件。分有前端和后端的(点击图片放大)。


前端堆栈我的方案如下:



Bigfoot 简介

“大脚 Bigfoot”是一款基于 JEE 平台研发的 Web 框架,继承了 Java 平台的高效、安全、稳定、跨平台等诸多优势,但却摒弃了传统 SSH 企业级架构所带来的庞大和臃肿,汲取了 PHP 的简洁和方便,非常适合互联网中小型网站的应用。

Bigfoot 是真正的开源、真正的免费,其代码直观、简洁,功能方面简单实用。该系统没有去做审核流程、复杂权限和日志等企业级的功能。对于这些功能,中小型互联网项目或许不是首要考虑;当前版本力求简单和通俗易懂的代码,也就是作为基础框架而考虑的。同时大脚也注重扩展性——更复杂的功能,可以留待二次开发。

个人认为 Java 在互联网应用之所以不及 PHP 那么受欢迎,其中一个主要是因为技术人员过分追求复杂的技术架构和为概念应用而应用(怕别人说技术不专业);搞得草根都不敢去用 Java 去了;于是这样的结果是严重阻碍了 Java 在互联网的应用和推广——而 PHP 在互联网的成功在于:简单和务实(PHP 的织梦成功正是这个原因)。我们的理念:Keep it simple, stupid,做一款简单实用的开源 Web。

迈普 CMS(MyPro Content Manage System)是以 Bigfoot 基础框架为依托的网站管理系统,具有懂 HTML 就能建站的优点,提供最便利、合理的使用方式。前端模板完全开放,可让用户随心所欲的自定义显示内容和显示方式。

“大脚 Bigfoot”整体特性:

  1. 免费、简单、开源
  2. 代码行数少,概念清晰,避免过渡设计
  3. 力求高聚合、低耦合
  4. 全栈式方案,包括前端控件和服务端接口,无缝对接
  5. 基于 JVM 的混合语言编程 = Java + JavaScript(服务端 Rhino)
  6. 基于 Java 1.7,积极采用 1.7 新语法,如 autoClose、多项异常抛出
  7. 特别适合从前端过来的开发人员,提供服务端 JS 环境
  8. 完备的文档、代码注释,并提供 JUnit 单元测试
  9. 谨慎采用第三方库,当前免 JAR 依赖(除数据库驱动外)。提倡“够用就好、就地取材”,例如,日志采用 JDK 自带的 Logger、JSON 转换让 JDK 自带的 Rhino 转换、数据连接池采用 Tomcat 自带的 Pool、页面标签就用 TagFiles/SimpleTag 甚至就是连 <%=……Java Code %> 都可以、使用 JSON 或 Map 作为通用的、交换的数据结构。

控制层特性:

  1. 回归简单性,结合灵活的 MVC 思想,强调前端、后端相分离,前端 = JavaBean + JSP;后端 JavaBean + Servlet。
  2. 基于 JSONTree 无序树的无限极分类,结构清晰,可维护性强。
  3. 提倡面向接口编程,实现了一个小型的 IOC 依赖注射和 AOP。
  4. 支持 JSON API 输出纯数据,与安卓、iOS、AJAX 甚至广义的客户端等等的无缝对接。

表示层特性:

  1. JSP 实际很强大完全可以做到类似 PHP 的页面优先的理念(互联网项目 UI 开发占了大量时间)——因此我们的数据绑定方式是 JSP 引入 JavaBean,而非 Servlet 控制。
  2. 有自己的前端库 Bigfoot.js(HTML5/CSS3/JavaScript),基于 LESS.js 预编译 CSS 器和 Node.js 的构建系统。
  3. 基于 JSP Tag Files 的模板继承机制,可复用性强。
  4. 模板语言基于 EL 表达式 和 SimpleTag。
  5. 后端管理界面可选使用 Ext JS。

数据层特性:

  1. 没有使用 ORM,提倡使用带变量的 SQL,提供简单的 SQL 封装手段和 DAO。
  2. 采用 Map 为输入、输出载体,如表单转换为 Map 再生成 SQL 语句;JDBC 返回数据采用 Map 为记录载体。
  3. 与 JS 引擎 Rhino 无缝对接,用 JS 定义一些方法,脚本语言 JS 在处理 JSON、字符串和正则表达式有极大的便利性和优势。
  4. 抛弃 Java POJO,改用 JS 定义实体,目的是为适合前后台所使用
  5. 使用 Tomcat 自带的数据库连接池 JDBC Pool。

最后,欢迎各位使用 Bigfoot!

Bigfoot 源码在

第一版,已废弃:http://code.taobao.org/p/bigfoot/src/

第二版,已废弃:http://code.taobao.org/p/bigfoot_v2/src/,请用 SVN 检出:http://code.taobao.org/svn/bigfoot_v2/。

第三版,基于 Spring + Spring MVC + MyBatis:http://code.taobao.org/p/bigfoot_v2/src/java_v3/

那些年我看过的 Servlet + JSP 开源框架:

EWeb4J 1.9.1 新版本发布 基于Servlet/JDBC的轻量级web开发框架

PandaJS: Rhino + MongoDB + Server-side JQuery Template

HashMap关系数据映射技术 

Eternal 框架

Nutz

Jfinal

Smart Framework

Tiny Framework

Firefly Framework

Solo

转:VO 与 PO 辨析

下面内容转载自 http://www.blogjava.net/lzhidj/archive/2011/02/21/344754.html

数据传输是程序员实现各种功能时刻需要考虑的问题,从数据模型的建立,到数据模型的转换,从数据的合法性验证,到数据类型的转化,我们要时刻小心,精心设计与组织。数据模型与数据传输可简单可复杂,完全取决于设计者的经验与意图,当然,项目的规模也是我们应该考虑的因素,一个小型项目实在没必要将问题复杂化。我们首先考虑数据从视图(View)传输到数据库(DB)的数据模型变化过程。用户从界面输入数据,此时,数据毫无结构可言,是零散的、无组织的,数据提交到控制器后,一方面考虑到 OOP 的严谨性,另一方面考虑到数据的封装,会将零散的无组织的数据封装成 Value Object(简称VO)对象,VO 就是 JavaBean,并传送到业务类中,在数据模型比较复杂的情况下,业务类的方法参数和返回值都应该是 VO 或 VO 的集合,VO 转换成 PO(Persistence Object)后传送到DAO,DAO 调用 Hibernate API 持久化数据。简单来说,业务类对外暴露的数据模型是 VO,DAO 对外暴露的数据模型是 PO。

数据从数据库传递到视图层的数据模型变化恰恰相反,Hibernate将数据库中的记录转换成 PO,PO 传递给业务类后转换成 VO,VO 被传送到视图层进行显示处理。以上转换过程如下图:

为什么同时需要 PO 和 VO?前面说过,这不是必须的,如果项目比较小,直接使用 PO 就行了。但 PO 有如下缺点:PO 反应了数据库的物理模型,向外暴露 PO 存在一定的风险;

  • PO过于僵化,无法适应变化莫测的业务需求;
  • PO在持久化状态下与数据库同步,可能导致数据意外修改;
  • PO将导致程序缺乏健壮性。

而VO没有PO的缺点,相对而言,VO更加灵活,能适应各种需求的变化,下面是 PO 和 VO 的区别:

  • VO 是用 new 关键字创建,由 GC 回收的。PO 则是向数据库中添加新数据时创建,删除数据库中数据时削除的。并且它只能存活在一个数据库连接中,断开连接即被销毁;
  • VO 是值对象,精确点讲它是业务对象,是存活在业务层的,是业务逻辑使用的,它存活的目的就是为数据提供一个生存的地方。PO 则是有状态的,每个属性代表其当前的状态。它是物理数据的对象表示。使用它,可以使我们的程序与物理数据解耦,并且可以简化对象数据与物理数据之间的转换;
  • VO 的属性是根据当前业务的不同而不同的,也就是说,它的每一个属性都一一对应当前业务逻辑所需要的数据的名称。PO 的属性是跟数据库表的字段一一对应的;
  • PO 一般只有一个,但对应的 VO 可能有多个。

我们举一个简单的例子来说明 VO 与 PO 的区别:比如要实现用户注册与登陆的功能,在物理模型中创建一个用户表,字段分别为用户 ID(标识列)、用户名、密码、注册日期等等,定义 PO 时应该有这四个字段的映射属性。现在,我们来实现用户注册这一功能,为了接收用户输入的注册信息,必须定义 VO,注册用户需要输入的信息有:用户名、密码1、密码2,这正好是 VO 的属性。而实现用户登陆功能时,用户需要输入的信息只有用户名和密码,所以,该 VO 的属性只有两个:用户名、密码。可以看出,PO 侧重于物理模型,而 VO 则更关注用户的实际需求。如下图所示:

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
1月前
|
开发框架 JavaScript 前端开发
如何选择合适的Web开发框架?
【9月更文挑战第1天】如何选择合适的Web开发框架?
54 1
|
6天前
|
缓存 Kubernetes Java
阿里云 SAE Web:百毫秒高弹性的实时事件中心的架构和挑战
SAE 事件中心通过智能诊断显示通知与用户连接起来,SAE WEB 百毫秒弹性实例给事件中心带来了新的实时性、海量数据和高吞吐的挑战,本篇将带您了解 SAE 整体事件中心的架构和挑战。
|
7天前
|
Web App开发 JavaScript 前端开发
构建高效Web应用:Node.js与Express框架的深度整合
【9月更文挑战第28天】在现代Web开发领域,Node.js和Express框架的结合已成为打造高性能、易扩展应用的黄金组合。本文将深入探讨如何利用这一技术栈优化Web应用架构,提供具体实践指导,并分析其性能提升的内在机制。通过代码示例,我们将展示从基础搭建到高级功能的实现过程,旨在为开发者提供一条清晰的学习路径,以实现技术升级和项目效率的双重提升。
20 3
|
11天前
|
JSON 安全 JavaScript
Web安全-JQuery框架XSS漏洞浅析
Web安全-JQuery框架XSS漏洞浅析
45 2
|
11天前
|
开发框架 JSON 缓存
震撼发布!Python Web开发框架下的RESTful API设计全攻略,让数据交互更自由!
在数字化浪潮推动下,RESTful API成为Web开发中不可或缺的部分。本文详细介绍了在Python环境下如何设计并实现高效、可扩展的RESTful API,涵盖框架选择、资源定义、HTTP方法应用及响应格式设计等内容,并提供了基于Flask的示例代码。此外,还讨论了版本控制、文档化、安全性和性能优化等最佳实践,帮助开发者实现更流畅的数据交互体验。
32 1
|
11天前
|
运维 安全 网络安全
Web安全-企业网络架构
Web安全-企业网络架构
16 1
|
13天前
|
机器学习/深度学习
ACM MM24:复旦提出首个基于扩散模型的视频非限制性对抗攻击框架,主流CNN和ViT架构都防不住它
【9月更文挑战第23天】复旦大学研究团队提出了ReToMe-VA,一种基于扩散模型的视频非限制性对抗攻击框架,通过时间步长对抗性潜在优化(TALO)与递归令牌合并(ReToMe)策略,实现了高转移性且难以察觉的对抗性视频生成。TALO优化去噪步骤扰动,提升空间难以察觉性及计算效率;ReToMe则确保时间一致性,增强帧间交互。实验表明,ReToMe-VA在攻击转移性上超越现有方法,但面临计算成本高、实时应用受限及隐私安全等挑战。[论文链接](http://arxiv.org/abs/2408.05479)
26 3
|
16天前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
31 5
|
28天前
|
Web App开发 前端开发 JavaScript
Web前端项目的跨平台桌面客户端打包方案之——CEF框架
Chromium Embedded Framework (CEF) 是一个基于 Google Chromium 项目的开源 Web 浏览器控件,旨在为第三方应用提供嵌入式浏览器支持。CEF 隔离了底层 Chromium 和 Blink 的复杂性,提供了稳定的产品级 API。它支持 Windows、Linux 和 Mac 平台,不仅限于 C/C++ 接口,还支持多种语言。CEF 功能强大,性能优异,广泛应用于桌面端开发,如 QQ、微信、网易云音乐等。CEF 开源且采用 BSD 授权,商业友好,装机量已超 1 亿。此外,GitHub 项目 CefDetector 可帮助检测电脑中使用 CEF
105 3
|
1月前
|
前端开发 安全 JavaScript
构建高效Web应用:前后端分离架构的实践
【9月更文挑战第4天】在数字时代,Web应用已成为企业与用户互动的主要平台。本文将介绍如何通过前后端分离的架构设计来构建高效的Web应用,探讨该架构的优势,并分享实现过程中的关键步骤和注意事项。文章旨在为开发者提供一种清晰、高效的开发模式,帮助其在快速变化的市场环境中保持竞争力。
下一篇
无影云桌面