詳解Java中的複合視圖設計模式

使用由多個子視圖組成的複合視圖。整個模板的每一個子視圖能夠總體動態地包括在內,而且能夠獨立於內容來管理頁面的佈局。css

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

爲簡單起見,這種模式分爲若干部分,如問題,動因,結構,解決方案,實施等。java

目錄

  • 問題
  • 動因
  • 解決方案
  • 說明
  • 結構 - 類圖,序列圖
  • 參與者和責任
  • 履行
  • 後果
  • 適用性
  • 現實世界的例子
  • 參考

問題

(問題部分描述了開發人員面臨的設計問題)spring

您但願從模塊化的原子組件部件構建視圖,這些部件組合在一塊兒以建立複合總體,同時獨立地管理內容和佈局。sql

動因

(本節描述了列出影響問題和解決方案的緣由和動機。動因列表突出了人們可能選擇使用模式並提供使用模式的理由的緣由)apache

  • 您須要在多個視圖中重複使用的常見子視圖,例如頁眉,頁腳和表格,這些子視圖可能出如今每一個頁面佈局中的不一樣位置。
  • 您在子視圖中有內容可能常常更改或可能受某些訪問控制的約束,例如限制對特定角色的用戶的訪問。
  • 您但願避免在多個視圖中直接嵌入和複製子視圖,這使得佈局更改難以管理和維護。

解決方案

使用由多個原子子視圖組成的複合視圖。整個模板的每一個子視圖能夠總體動態地包括在內,而且能夠獨立於內容來管理頁面的佈局。設計模式

例如,門戶網站包含許多獨立的子視圖,例如新聞源,天氣信息和單個頁面上的股票報價。能夠獨立於內容來管理頁面的佈局。bash

此模式的另外一個好處是,Web設計人員能夠對站點的佈局進行原型設計,將靜態內容插入每一個模板區域。隨着站點開發的進展,實際內容將替換這些佔位符。該方法提供了改進的模塊化和可重用性,以及改進的可維護性。架構

結構體

咱們使用UML類圖來顯示解決方案的基本結構,本節中的UML序列圖介紹瞭解決方案的動態機制。併發

下面是表示Composite View Design Pattern關係的類圖。

類圖

序列圖

參與者和責任

Client - 客戶端發送到視圖。

View- 視圖。

SimpleView- 表示的複合總體的原子部分。它也被稱爲視圖片斷或子視圖。

CompositeView- 複合視圖由多個視圖組成。這些視圖中的每個要麼是一個簡單視圖,要麼自己多是一個複合視圖。

Template- 模板,表明視圖佈局。

這種模式如何運做

爲了理解這種模式,咱們舉一個例子。在下圖中,您能夠看到網頁的典型結構。

這種結構稱爲「經典佈局」。模板根據此佈局組織頁面,將每一個「塊」放在所需的位置,以使標題上升,頁腳向下等。

可能會發生這種狀況,例如點擊連接,只須要更改頁面的一部分,一般是正文。

如您所見,頁面不一樣,但它們的區別僅在於正文部分。可是請注意,頁面是不一樣的,它不像框架集中的框架刷新!

使用複合視圖模式,頁面的其餘部分已被重用,而且已保留佈局一致性。

履行

在此示例中,View管理是使用標準JSP標記實現的,例如jsp:include標記。使用標準標籤來管理視圖的佈局和組合是一種易於實施的策略。

標準標籤視圖管理策略示例 :

<html>
   <body>
      <jsp:include
         page="/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 {

    @Override
    protected Class << ? > [] getRootConfigClasses() {
        return new Class[] {
            ApplicationConfiguration.class
        };
    }

    @Override
    protected Class << ? > [] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {
            "/"
        };
    }
}
複製代碼

最後,在ApplicationConfiguration類中,咱們使用TilesConfigurer和TilesViewResolver類來實現集成:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.baeldung.tiles.springmvc")
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
    @Bean
    public TilesConfigurer tilesConfigurer() {
        TilesConfigurer tilesConfigurer = new TilesConfigurer();
        tilesConfigurer.setDefinitions(
            new String[] {
                "/WEB-INF/views/**/tiles.xml"
            });
        tilesConfigurer.setCheckRefresh(true);

        return tilesConfigurer;
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        TilesViewResolver viewResolver = new TilesViewResolver();
        registry.viewResolver(viewResolver);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
            .addResourceLocations("/static/");
    }
}
複製代碼

第4步: 平鋪模板文件

<html>
    <head>
        <meta
          http-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等多個知識點的架構資料)

比你優秀的對手在學習,你的仇人在磨刀,你的閨蜜在減肥,隔壁老王在練腰, 咱們必須不斷學習,不然咱們將被學習者超越!

趁年輕,使勁拼,給將來的本身一個交代!

相關文章
相關標籤/搜索