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

news/2024/7/5 2:23:48

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

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


http://lihuaxi.xjx100.cn/news/243935.html

相关文章

LINUNX下PHP下载中文文件名代码

function get_basename($filename){ return preg_replace(/^.[\\\\\\/]/, , $filename); } $file "/tmp/你好.txt";$filename get_basename($file);header("Content-type: application/octet-stream");//处理中文文件名$ua $_SERVER["HTTP…

Android App Icon 替换

今天老板提出有一个需求, 说咱家App icon太丑, 老板说随便什么icon都行 1. 为了随便找一个icon, 我去google了一个图 2. ok, 随便找到一个icon, 下载下来保存文件叫做 jay_web_app.png, 长得还行 3. Android icon 替换开始, 首先找到原来icon的位置, 怎么找呢? 有一个简单直接…

Mybatis源码阅读之三

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

如何创建可扩展表视图中的iOS 学习和拓展优化(有待更新)

首先介绍老外的文章&#xff1a;《How To Create an Expandable Table View in iOS》这是老外用Swift实现的&#xff0c;对应的老外github项目源码&#xff1a;https://github.com/appcoda/expandable-table-view小编经过学习了老外的Expandable Table View然后用Objective-C实…

python学习 第七篇 sql优化

查询单条语句&#xff1a;用来获取用户列表和单个用户>>> fields["id","name","name_cn","email","mobile"] >>> sql"select %s from users where name admin" % ,.join(field…

数据结构(队列实现篇)

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

2016.01.04 论文改重

今天的任务是修改查重的问题&#xff0c;另外加入参考文献。 其中&#xff0c;上午的时间完成论文查重。 下午的时间完成参考文献的丰富和标记。 晚上的时间完成DOM基础&#xff08;李炎恢&#xff09;的学习 预计晚上八点到晚上十点 优先级&#xff1a;论文查重&#xff0c;参…

java连接mysql数据库(jsp显示和控制台显示)

很多事情&#xff0c;在我们没有做之前我们觉得好难&#xff0c;但是只要你静下心来&#xff0c;毕竟这些都是人搞出来的&#xff0c;只要你是人&#xff0c;那就一定可以明白。 配置&#xff1a;JDK1.8&#xff0c;MySQL5.7&#xff0c;eclipse&#xff1a;Neon Release (4.6.…