【Java设计模式】组合视图模式:增强应用程序中UI的一致性

embedded/2024/10/18 16:45:42/

【Java设计模式】组合视图模式:增强应用程序中UI的一致性

一、概述

在Java中,组合视图设计模式有助于管理复杂的层次视图。本文将详细介绍该模式的意图、解释、编程示例、适用场景、实际应用、优点和权衡。同时,还将提供示例代码的下载链接,方便读者进行学习和实践。

二、组合视图设计模式的意图

组合视图设计模式的主要目标是将对象组合成树结构,以表示部分 - 整体层次结构。这允许客户端统一对待单个对象和对象的组合,简化了复杂层次视图的管理。

三、组合视图模式的详细解释及实际示例

  1. 实际示例
    • 组合视图设计模式的一个现实世界示例是Web应用程序中仪表板的布局。考虑一个金融仪表板,它显示各种小部件,如股票图表、最近的交易、账户余额和新闻提要。这些小部件中的每一个都是可以独立更新和管理的单独视图组件。通过使用组合视图模式,这些单独的小部件被组合成一个统一的仪表板视图。这种方法允许轻松地重新组织仪表板,添加新的小部件而不会干扰现有的小部件,并对整体布局进行一致的管理。这种视图的层次结构组合反映了仪表板的不同部分如何被视为单独的实体和更大整体的一部分。
  2. 通俗解释
    • 组合视图模式是指一个主视图由较小的子视图组成。这个组合视图的布局基于一个模板。然后,视图管理器决定在这个模板中包含哪些子视图。
  3. 维基百科解释
    • 组合视图由多个原子子视图组成。模板的每个组件都可以动态地包含在整体中,页面的布局可以独立于内容进行管理。该解决方案基于模块化动态和静态模板片段的包含和替换来创建组合视图。它通过鼓励模块化设计促进了视图原子部分的重用。

四、Java中组合视图模式的编程示例

一个新闻网站希望根据用户的偏好向不同用户显示当前日期和新闻。新闻网站将根据用户的兴趣替换不同的新闻提要组件,默认为本地新闻。
由于这是一个Web开发模式,需要一个服务器来演示它。这个示例使用Tomcat 10.0.13来运行Servlet,并且这个编程示例仅适用于Tomcat 10+。
首先,有一个AppServlet,它是一个在Tomcat 10+上运行的HttpServlet

java">public class AppServlet extends HttpServlet {private String msgPartOne = "<h1>This Server Doesn't Support";private String msgPartTwo = "Requests</h1>\n"+ "<h2>Use a GET request with boolean values for the following parameters<h2>\n"+ "<h3>'name'</h3>\n<h3>'bus'</h3>\n<h3>'sports'</h3>\n<h3>'sci'</h3>\n<h3>'world'</h3>";private String destination = "newsDisplay.jsp";public AppServlet() {}@Overridepublic void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {RequestDispatcher requestDispatcher = req.getRequestDispatcher(destination);ClientPropertiesBean reqParams = new ClientPropertiesBean(req);req.setAttribute("properties", reqParams);requestDispatcher.forward(req, resp);}@Overridepublic void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {resp.setContentType("text/html");PrintWriter out = resp.getWriter();out.println(msgPartOne + " Post " + msgPartTwo);}@Overridepublic void doDelete(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {resp.setContentType("text/html");PrintWriter out = resp.getWriter();out.println(msgPartOne + " Delete " + msgPartTwo);}@Overridepublic void doPut(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {resp.setContentType("text/html");PrintWriter out = resp.getWriter();out.println(msgPartOne + " Put " + msgPartTwo);}
}

这个Servlet不属于该模式的一部分,它只是将GET请求转发到正确的JSP。PUT、POST和DELETE请求不受支持,只会显示错误消息。
此示例中的视图管理通过一个JavaBean类:ClientPropertiesBean完成,该类存储用户偏好。

java">public class ClientPropertiesBean implements Serializable {private static final String WORLD_PARAM = "world";private static final String SCIENCE_PARAM = "sci";private static final String SPORTS_PARAM = "sport";private static final String BUSINESS_PARAM = "bus";private static final String NAME_PARAM = "name";private static final String DEFAULT_NAME = "DEFAULT_NAME";private boolean worldNewsInterest;private boolean sportsInterest;private boolean businessInterest;private boolean scienceNewsInterest;private String name;public ClientPropertiesBean() {worldNewsInterest = true;sportsInterest = true;businessInterest = true;scienceNewsInterest = true;name = DEFAULT_NAME;}public ClientPropertiesBean(HttpServletRequest req) {worldNewsInterest = Boolean.parseBoolean(req.getParameter(WORLD_PARAM));sportsInterest = Boolean.parseBoolean(req.getParameter(SPORTS_PARAM));businessInterest = Boolean.parseBoolean(req.getParameter(BUSINESS_PARAM));scienceNewsInterest = Boolean.parseBoolean(req.getParameter(SCIENCE_PARAM));String tempName = req.getParameter(NAME_PARAM);if (tempName == null || tempName == "") {tempName = DEFAULT_NAME;}name = tempName;}// Lombok生成的getter和setter
}

这个JavaBean有一个默认构造函数,还有一个接受HttpServletRequest的构造函数。
这个第二个构造函数接受请求对象,解析出包含用户对不同类型新闻偏好的请求参数。
新闻页面的模板在newsDisplay.jsp

<html>
<head><style>h1 {text-align: center;}h2 {text-align: center;}h3 {text-align: center;}.centerTable {margin-left: auto;margin-right: auto;}table {border: 1px solid black;}tr {text-align: center;}td {text-align: center;}</style>
</head>
<body>
<%ClientPropertiesBean propertiesBean = (ClientPropertiesBean) request.getAttribute("properties");%>
<h1>Welcome <%= propertiesBean.getName()%></h1>
<jsp:include page="header.jsp"></jsp:include>
<table class="centerTable"><tr><td></td><% if(propertiesBean.isWorldNewsInterest()) { %><td><%@include file="worldNews.jsp"%></td><% } else { %><td><%@include file="localNews.jsp"%></td><% } %><td></td></tr><tr><% if(propertiesBean.isBusinessInterest()) { %><td><%@include file="businessNews.jsp"%></td><% } else { %><td><%@include file="localNews.jsp"%></td><% } %><td></td><% if(propertiesBean.isSportsInterest()) { %><td><%@include file="sportsNews.jsp"%></td><% } else { %><td><%@include file="localNews.jsp"%></td><% } %></tr><tr><td></td><% if(propertiesBean.isScienceNewsInterest()) { %><td><%@include file="scienceNews.jsp"%></td><% } else { %><td><%@include file="localNews.jsp"%></td><% } %><td></td></tr>
</table>
</body>
</html>

这个JSP页面是模板。它声明了一个包含三行的表格,第一行有一个组件,第二行有两个组件,第三行有一个组件。
文件中的脚本是视图管理策略的一部分,根据JavaBean中的用户偏好包含不同的原子子视图。
以下是组合中使用的模拟原子子视图的两个示例:businessNews.jsp

<html>
<head><style>h2 {text-align: center;}table {border: 1px solid black;}tr {text-align: center;}td {text-align: center;}</style>
</head>
<body>
<h2>Generic Business News
</h2>
<table style="margin-right: auto; margin-left: auto"><tr><td>Stock prices up across the world</td><td>New tech companies to invest in</td></tr><tr><td>Industry leaders unveil new project</td><td>Price fluctuations and what they mean</td></tr>
</table>
</body>
</html>

localNews.jsp

<html>
<body>
<div style="text-align: center"><h3>Generic Local News</h3><ul style="list-style-type: none"><li>Mayoral elections coming up in 2 weeks</li><li>New parking meter rates downtown coming tomorrow</li><li>Park renovations to finish by the next year</li><li>Annual marathon sign ups available online</li></ul>
</div>
</body>
</html>

不同的子视图,如worldNews.jspbusinessNews.jsp等,根据请求参数有条件地包含。
如何使用
要尝试这个示例,请确保您安装了Tomcat 10+。设置您的IDE从模块构建WAR文件,并将该文件部署到服务器
IntelliJ:
在“运行”和“编辑配置”下,确保Tomcat服务器是运行配置之一。转到“部署”选项卡,并确保有一个名为“composite - view:war exploded”的工件正在构建。如果不存在,请添加一个。
确保该工件是根据“web”目录的内容和模块的编译结果构建的。将工件的输出指向一个方便的位置。运行配置并查看着陆页,按照该页面上的说明继续。

五、何时在Java中使用组合视图模式

当出现以下情况时使用组合视图设计模式

  1. 您想要表示对象的部分 - 整体层次结构。
  2. 您预计组合结构将来可能会包含任何新组件。
  3. 您希望客户端能够忽略对象组合和单个对象之间的区别。客户端将统一对待组合结构中的所有对象。

六、组合视图模式在Java中的实际应用

  1. 图形用户界面(GUI),其中小部件可以包含其他小部件(例如,包含面板、按钮和文本字段的窗口)。
  2. 文档结构,例如包含行的表格的表示,行又包含单元格,所有这些都可以作为统一层次结构中的元素进行处理。

七、组合视图模式的优点和权衡

优点:

  1. 添加新组件的高度灵活性:由于组合和叶节点被统一对待,因此更容易添加新的组件类型。
  2. 简化客户端代码:客户端可以统一对待组合结构和单个元素,减少了客户端代码的复杂性。

权衡:

  1. 过度泛化:如果将所有内容都设计为组合,系统设计可能会变得更加复杂,特别是如果您的应用程序不需要这样做。
  2. 约束执行困难:将组合的组件限制为仅某些类型可能会更困难。

八、源码下载

https://download.csdn.net/download/weixin_42545951/89696137

通过本文的介绍,相信大家对Java中的组合视图模式有了更深入的了解。在实际开发中,合理运用该模式可以提高UI的一致性和可维护性,但需要注意避免过度泛化和约束执行的困难。


http://www.ppmy.cn/embedded/103108.html

相关文章

Springboot里集成Mybatis-plus、ClickHouse

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; Springboot里集成Mybati…

android studio 新建java工程, 安卓新建项目,android studio2024 如何新建java项目

主要解决&#xff0c;新增安卓工程&#xff0c;没有java选项 1. 点击左上角FIle -> New -> 2. 选择 no activity 选项&#xff0c; 然后next 3. langua 就可以选择java 了。name自己定义项目名称&#xff0c;项目存储地址&#xff0c;包名。 配置完成选择finish. 4. fin…

AWS 中的信任策略的危险

介绍 使用过 Amazon Web Services (AWS) 的每个人都知道,云环境有一种独特的方式来授予用户和资源的访问权限。这是通过允许用户和/或资源临时承担角色来实现的。这些类型的操作之所以可能,是因为分配给这些角色的信任策略。信任策略是附加到 AWS 环境中每个角色的文档。此文…

虚幻5|技能栏优化(1)---优化技能UI,并添加多个技能

一.添加多一个技能格子并进行初始化清楚 1.打开技能UI把原先的事件构造后面的蓝图&#xff0c;全部选中&#xff0c;右键创建一个函数&#xff0c;命名为初始化 2.添加以下两个蓝图&#xff0c;用于清楚技能格子内容 2.在之前&#xff0c;事件构造后面的蓝图&#xff0c;不需…

功能测试常用的测试用例大全

登录、添加、删除、查询模块是我们经常遇到的&#xff0c;这些模块的测试点该如何考虑 1)登录 ① 用户名和密码都符合要求(格式上的要求) ② 用户名和密码都不符合要求(格式上的要求) ③ 用户名符合要求&#xff0c;密码不符合要求(格式上的要求) ④ 密码符合要求&#xff0c;…

UTONMOS:探索未来游戏的元宇宙纪元新篇章

元宇宙游戏&#xff0c;作为融合了虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff09;、区块链、人工智能&#xff08;AI&#xff09;等前沿技术的综合性数字世界&#xff0c;元宇宙游戏不仅重新定义了游戏的边界&#xff0c;更预示着一个沉浸式、交互性…

「bug」nvitop ERROR: Failed to initialize curses

nvitop 作为一个优秀个 Nvidia显卡查询库&#xff0c;简单易用且显示信息十分丰富&#xff0c;相比 Nvidia-smi 更方便&#xff0c;简直是每个 开发人员必备的库&#xff0c;安装也十分方便&#xff0c;直接采用 pip install nvitop 即可&#xff0c;调用的时候也是直接在 Term…

【秋招笔试】8.21华为秋招-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…