当前位置: 首页 > 编程日记 > 正文

详解Java中的复合视图设计模式

使用由多个子视图组成的复合视图。整个模板的每个子视图可以整体动态地包括在内,并且可以独立于内容来管理页面的布局。

Apache Tiles和SiteMesh 框架使用Composite View Design Pattern。

为简单起见,这种模式分为若干部分,如问题,动因,结构,解决方案,实施等。

目录

  • 问题
  • 动因
  • 解决方案
  • 说明
  • 结构 - 类图,序列图
  • 参与者和责任
  • 履行
  • 后果
  • 适用性
  • 现实世界的例子
  • 参考

问题

(问题部分描述了开发人员面临的设计问题)

您希望从模块化的原子组件部件构建视图,这些部件组合在一起以创建复合整体,同时独立地管理内容和布局。

动因

(本节描述了列出影响问题和解决方案的原因和动机。动因列表突出了人们可能选择使用模式并提供使用模式的理由的原因)

  • 您需要在多个视图中重复使用的常见子视图,例如页眉,页脚和表格,这些子视图可能出现在每个页面布局中的不同位置。
  • 您在子视图中有内容可能经常更改或可能受某些访问控制的约束,例如限制对特定角色的用户的访问。
  • 您希望避免在多个视图中直接嵌入和复制子视图,这使得布局更改难以管理和维护。

解决方案

使用由多个原子子视图组成的复合视图。整个模板的每个子视图可以整体动态地包括在内,并且可以独立于内容来管理页面的布局。

例如,门户网站包含许多独立的子视图,例如新闻源,天气信息和单个页面上的股票报价。可以独立于内容来管理页面的布局。

此模式的另一个好处是,Web设计人员可以对站点的布局进行原型设计,将静态内容插入每个模板区域。随着站点开发的进展,实际内容将替换这些占位符。该方法提供了改进的模块化和可重用性,以及改进的可维护性。

结构体

我们使用UML类图来显示解决方案的基本结构,本节中的UML序列图介绍了解决方案的动态机制。

下面是表示Composite View Design Pattern关系的类图。

类图

序列图

参与者和责任

Client - 客户端发送到视图。

View- 视图。

SimpleView- 表示的复合整体的原子部分。它也被称为视图片段或子视图。

CompositeView- 复合视图由多个视图组成。这些视图中的每一个要么是一个简单视图,要么本身可能是一个复合视图。

Template- 模板,代表视图布局。

这种模式如何运作

为了理解这种模式,我们举一个例子。在下图中,您可以看到网页的典型结构。

这种结构称为“经典布局”。模板根据此布局组织页面,将每个“块”放在所需的位置,以使标题上升,页脚向下等。

可能会发生这种情况,例如点击链接,只需要更改页面的一部分,通常是正文。

如您所见,页面不同,但它们的区别仅在于正文部分。但是请注意,页面是不同的,它不像框架集中的框架刷新!

使用复合视图模式,页面的其他部分已被重用,并且已保留布局一致性。

履行

在此示例中,View管理是使用标准JSP标记实现的,例如jsp:include标记。使用标准标签来管理视图的布局和组合是一种易于实施的策略。

标准标签视图管理策略示例 :

<html><body><jsp:includepage="/jsp/CompositeView/javabean/banner.seg" flush="true"/><table width="100%"><tr align="left" valign="middle"><td width="20%"><jsp:include page="/jsp/CompositeView/javabean/ProfilePane.jsp"flush="true"/></td><td width="70%" align="center"><jsp:include page="/jsp/CompositeView/javabean/mainpanel.jsp"lush="true"/></td></tr></table><jsp:include page="/jsp/CompositeView/javabean/footer.seg"flush="true"/></body>
</html>
复制代码

Apache Tiles与Spring MVC集成的 示例

Apache Tiles是一个免费的开源模板框架,完全基于Composite设计模式。在Apache Tiles中,通过组合称为Tiles的子视图组合来构建页面。

第1步: 提供依赖关系配置

<dependency><groupId>org.apache.tiles</groupId><artifactId>tiles-jsp</artifactId><version>3.0.7</version>
</dependency>
复制代码

第2步:定义平铺布局文件

<tiles-definitions><definition name="template-def"template="/WEB-INF/views/tiles/layouts/defaultLayout.jsp">  <put-attribute name="title" value="" />  <put-attribute name="header"value="/WEB-INF/views/tiles/templates/defaultHeader.jsp" />  <put-attribute name="menu"value="/WEB-INF/views/tiles/templates/defaultMenu.jsp" />  <put-attribute name="body" value="" />  <put-attribute name="footer"value="/WEB-INF/views/tiles/templates/defaultFooter.jsp" />  </definition>  <definition name="home" extends="template-def">  <put-attribute name="title" value="Welcome" />  <put-attribute name="body"value="/WEB-INF/views/pages/home.jsp" />  </definition>  
</tiles-definitions>
复制代码

第3步: ApplicationConfiguration和其他类

@Controller
@RequestMapping("/")
public class ApplicationController {@RequestMapping(value = {"/"},method = RequestMethod.GET)public String homePage(ModelMap model) {return "home";}@RequestMapping(value = {"/apachetiles"},method = RequestMethod.GET)public String productsPage(ModelMap model) {return "apachetiles";}@RequestMapping(value = {"/springmvc"},method = RequestMethod.GET)public String contactUsPage(ModelMap model) {return "springmvc";}
}public class ApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class << ? > [] getRootConfigClasses() {return new Class[] {ApplicationConfiguration.class};}@Overrideprotected Class << ? > [] getServletConfigClasses() {return null;}@Overrideprotected String[] getServletMappings() {return new String[] {"/"};}
}
复制代码

最后,在ApplicationConfiguration类中,我们使用TilesConfigurer和TilesViewResolver类来实现集成:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.baeldung.tiles.springmvc")
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {@Beanpublic TilesConfigurer tilesConfigurer() {TilesConfigurer tilesConfigurer = new TilesConfigurer();tilesConfigurer.setDefinitions(new String[] {"/WEB-INF/views/**/tiles.xml"});tilesConfigurer.setCheckRefresh(true);return tilesConfigurer;}@Overridepublic void configureViewResolvers(ViewResolverRegistry registry) {TilesViewResolver viewResolver = new TilesViewResolver();registry.viewResolver(viewResolver);}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("/static/");}
}
复制代码

第4步: 平铺模板文件

<html><head><metahttp-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title><tiles:getAsString name="title" /></title><link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link></head><body><div class="flex-container"><tiles:insertAttribute name="header" /><tiles:insertAttribute name="menu" /><article class="article"><tiles:insertAttribute name="body" /></article><tiles:insertAttribute name="footer" /></div></body>
</html>
复制代码

后果

  • 改善模块化和重用
  • 添加基于角色或基于策略的控制
  • 增强可维护性
  • 降低可维护性
  • 降低性能

写在最后

最后,欢迎做Java的工程师朋友们加入Java高级架构进阶Qqun:963944895

群内有技术大咖指点难题,还提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)

比你优秀的对手在学习,你的仇人在磨刀,你的闺蜜在减肥,隔壁老王在练腰, 我们必须不断学习,否则我们将被学习者超越!

趁年轻,使劲拼,给未来的自己一个交代!

转载于:https://juejin.im/post/5cdd601de51d456e2446fda2

相关文章:

CI流水线配置文件参数详解(一)

文章目录4. 参数详解(一)4.1 script4.2 image 指定使用Docker镜像。如 iamge:name &#xff0c;暂时忽略。4.3 before_script 用于定义在所有作业之前需要执行的命令&#xff0c;比如更新代码、安装依赖、打印调试信息之类的事情。4.4 after_script4.5 stages 定义流水线全局可…

Elasticsearch的前后台运行与停止(rpm包方式)

对应&#xff0c;这es的下载&#xff0c;需要rpm包。 Elasticsearch-2.4.3的下载&#xff08;图文详解&#xff09; 建议用root用户 [rootdjt002 elasticsearch-2.4.3]$ pwd/usr/local/elasticsearch/elasticsearch-2.4.3 [rootdjt002 elasticsearch-2.4.3]$ rpm -ivh elastic…

SURF 特征检测及匹配

#include <opencv2/opencv.hpp> #include <opencv2/xfeatures2d.hpp> #include <opencv2/xfeatures2d/nonfree.hpp> #include <iostream>using namespace cv::xfeatures2d; using namespace std; using namespace cv;// 计算图像的SURF特征及匹配 floa…

Mybatis源码阅读之三

2019独角兽企业重金招聘Python工程师标准>>> 由前面的系列二分析到MapperMethod的execute方法&#xff0c;我们接着分析MapperMethod。如下List-1: List-1 public class MapperMethod {private final SqlCommand command;private final MethodSignature method;publ…

Vim快捷键键位图

https://www.runoob.com/w3cnote/all-vim-cheatsheat.html

简单几步写一个laravel扩展包

为什么80%的码农都做不了架构师&#xff1f;>>> laravel使用composer来管理扩展包&#xff0c;理解composer和laravel的开发模式&#xff0c;可以通过简单的几个步骤&#xff0c;快速写出一个laravel扩展包。 全新的laravel5.4环境安装 composer create-project la…

ORB 特征检测与匹配

#include <opencv2/opencv.hpp> #include <opencv2/xfeatures2d.hpp> #include <opencv2/xfeatures2d/nonfree.hpp> #include <iostream>using namespace cv::xfeatures2d; using namespace std; using namespace cv; // 计算图像的ORB特征及匹配 cv::…

数据结构(队列实现篇)

在数据结构与算法中&#xff0c;队列queue是一种受限的线性储存结构&#xff0c;特殊之处在于它只允许在表的前端front进行删除操作&#xff0c;而在表的后端rear进行插入操作&#xff0c;和栈一样&#xff0c;队列是一种操作受限制的线性表。进行插入操作的端称为队尾&#xf…

Markdown编辑器使用

Markdown编辑器使用欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚…

HOGDescriptor 描述类

struct CV_EXPORTS HOGDescriptor {// 高斯平滑参数enum { DEFAULT_WIN_SIGMA -1 };// 检测窗口的最大数量enum { DEFAULT_NLEVELS 64 };// 描述符存储格式enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL };// 创建了特征描述符和检测器HOGDescriptor(Size win_si…

Linux----进程概念

程序 : 程序指的是一系列有逻辑, 有顺序结构的指令.进程 : 进程从两个角度来说:1 用户角度: 进程从用户角度来说就是运行中的程序2 操作系统的角度: 进程是操作系统对运行中程序的描述信息, 叫做进程描述符(程序控制块)简称PCBPCB : 在Linux下PCB指的是在内核中的task_struct 结…

codecheck

codecheck scan-build: clang-tools集成的静态检查工具, 使用clang static analyzer进行静态检查&#xff0c;使用方便 https://clang-analyzer.llvm.org/scan-build.html https://manpages.ubuntu.com/manpages/bionic/man1/scan-build.1.html CodeChecker: 爱立信推出的静…

ubuntu安装chrome浏览器

PPA方法&#xff0c;免FQ&#xff0c;否则&#xff0c;你得FQ下载chrome&#xff0c;你Firefox VPN配置好了吗&#xff01;&#xff01;&#xff01; wget -q -O - https://raw.githubusercontent.com/longhr/ubuntu1604hub/master/linux_signing_key.pub | sudo apt-key add s…

java中的注解(二)

今天我继续来介绍java中的注解。注解与接口和类不同的是注解是不允许继承的&#xff0c;但是注解中有一个和继承有关的元注解&#xff1a;Inherited。如果我们在定义注解时候加上这个元注解那么我们就可以在子类中监测到该注解的存在。 Target(ElementType.TYPE) Inherited Ret…

【C++】random随机数与【C++11】/rand()和srand()的用法

文章目录随机数1. c 11 random随机数的使用&#xff08;推荐使用&#xff09;1.11.21.31.42.1 C中随机函数rand()和srand()的用法&#xff08;老本版&#xff09;2.2 限制随机数的范围随机数 C 提供了一组函数以生成和使用随机数字。随机数字就是从一组可能的值中进行随机选择…

快速区域积分直方图实现

void cacHOGinCell(Mat& HOGCellMat,Rect roi,std::vector<Mat>& integrals) {// 实现快速积分HOGint x0 roi.x,y0 roi.y;int x1 x0 roi.width&#xff1b;int y1 y0 roi.height;for(int i 0; i < NBINS; i){// 根据矩阵的上下左右坐标计算Mat integra…

Resultset获取行数和列数

为什么80%的码农都做不了架构师&#xff1f;>>> 在Java中&#xff0c;获得ResultSet的总行数的方法有以下几种。 第一种&#xff1a;利用ResultSet的getRow方法来获得ResultSet的总行数 Statement stmt con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,Re…

object.create()

语法&#xff1a; Object.create(proto, [propertiesObject]) //方法创建一个新对象&#xff0c;使用现有的对象来提供新创建的对象的proto。 参数&#xff1a;proto : 必须。表示新建对象的原型对象&#xff0c;即该参数会被赋值到目标对象(即新对象&#xff0c;或说是最后返回…

codecheck_use_record

文章目录Step 1: Integrate CodeChecker into your build systemStep 2: Analyze your codeStep 3: Run the analysisStep 4: View the analysis results in the command lineStep 5: Hint: You can do the 1st and the 2nd step in one round by executing checkstep 6: Expor…

centos6.5 rsync+inotify同步配置笔记

以两台服务器为例&#xff1a; 主服务器&#xff1a; 192.168.1.100 从服务器&#xff1a; 192.168.1.101 1.安装rsync (主服务器与从服务器同时安装) 使用xinetd管理rsync yum install rsync xinetd 设置开机启动 vi /etc/xinetd.d/rsync ... 修改为 disable no ... 启动xin…

HOG 特征计算实现

// 获取HOG直方图 cv::Mat getHog(Point pt,std::vector<Mat> &integrals) {// 判断当前点的位置是否符合条件 if( pt.x - R < 0 ||pt.y - R < 0 ||pt.x R > integrals[0].cols ||pt.y R > integrals[0].rows ){return Mat();}// 直方图Mat hist(Size(…

Spring+SpringMVC+Mybatis整合

一、简单测试工程搭建1、Mybatis所需要的的jar包&#xff08;包含数据库驱动包和相关的日志包&#xff09;、SpringMVC和Spring的jar包2、然后构建一个基本的工程&#xff0c;这里我们使用mapper代理的方式进行Mybatis的编写&#xff0c;关于mapper代理请参考Mybatis简单入门中…

【Tools】Markdown数学符号公式(史上最全公式表)

Markdown数学符号&公式 文章目录Markdown数学符号&公式1. 希腊字母表2. 希腊字母3. 数学符号表4. 数学符号5. 数学符号补充表6. 数学符号补充1. 希腊字母表 符号代码符号代码α\alphaα\alphaA\AlphaA\Alphaβ\betaβ\betaB\BetaB\Betaγ\gammaγ\gammaΓ\GammaΓ\gam…

Editplus下载、安装并最佳配色方案(强烈推荐)

不多说&#xff0c;直接上干货&#xff01; Editplus下载 第一步&#xff1a;进入官网 https://www.editplus.com/ 第二步&#xff1a;下载 https://www.editplus.com/download.html Editplus安装 我这里&#xff0c;直接以一个压缩包来安装&#xff0c;需要的&#xff0c;请…

MySQL数据库开发规范-EC

最近一段时间一边在线上抓取SQL来优化&#xff0c;一边在整理这个开发规范&#xff0c;尽量减少新的问题SQL进入生产库。今天也是对公司的开发做了一次培训&#xff0c;PPT就不放上来了&#xff0c;里面有十来个生产SQL的案例。因为规范大部分还是具有通用性&#xff0c;所以也…

操作系统与内存管理

操作系统内存管理 文章目录操作系统内存管理1. 虚拟地址空间2. 内存地址空间含义及分配3. 虚拟内存诞生的前世与今生&#xff1f;3.1 内存管理的好处3.2 **内存管理实现总体策略**4. 不同进程如何划分内存地址空间&#xff1f;5 内存分配与回收5.1 buffer和cache5.2 malloc背后…

圆形 LBP 特征

template <typename _Tp> staticinline void elbp_(InputArray _src, OutputArray _dst,int radius, int neighbors) {// 得到数据矩阵Mat src _src.getMat();// 输出矩阵_dst.create(src.rows-2*radius, src.cols-2*radius, CV_32SC1);Mat dst _dst.getMat();// 初始化…

40个Java多线程问题总结

&#xff08;转&#xff09; 这篇文章作者写的真是不错 40个问题汇总 1、多线程有什么用&#xff1f; 一个可能在很多人看来很扯淡的一个问题&#xff1a;我会用多线程就好了&#xff0c;还管它有什么用&#xff1f;在我看来&#xff0c;这个回答更扯淡。所谓"知其然知其所…

SLAM十四讲笔记1

文章目录ch02 初识SLAMch02-01 经典视觉SLAM框架ch02-02 SLAM问题的数学表述ch03 三维空间刚体运动ch03.01 旋转矩阵&#xff1a;点和向量,坐标系01 向量a在线性空间的基[e1,e2,e3][e_1,e_2,e_3][e1​,e2​,e3​]下的坐标为[a1,a2,a3]T[a_1,a_2,a_3]^T[a1​,a2​,a3​]T.02 向量…

12、OpenCV实现图像的空间滤波——图像平滑

1、空间滤波基础概念 1、空间滤波基础 空间滤波一词中滤波取自数字信号处理&#xff0c;指接受或拒绝一定的频率成分&#xff0c;但是空间滤波学习内容实际上和通过傅里叶变换实现的频域的滤波是等效的&#xff0c;故而也称为滤波。空间滤波主要直接基于领域&#xff08;空间域…