Composite View Design Pattern in Java

Use Composite Views that are composed of multiple atomic subviews. Each subview of the overall template can be included dynamically in the whole, and the layout of the page can be managed independently of the content. 
Apache Tiles and SiteMesh frameworks uses Composite View Design Pattern. 
This pattern is divided into a number of sections for simplicity like problem, forces, structure, solution, implementation etc.

Table of contents
Problem
Forces
Solution
Explanation
Structure - Class Diagram, Sequence Diagram
Participants and Responsibilities
Implementation
Consequences
Applicability
Real world examples
References

Problem

(Problem section describes the design issues faced by the developer)
You want to build a view from modular, atomic component parts that are combined to create a composite whole while managing the content and the layout independently.

Forces

(This section describes Lists the reasons and motivations that affect the problem and the solution. The list of forces highlights the reasons why one might choose to use the pattern and provides a justification for using the pattern)
  • You want common subviews, such as headers, footers, and tables reused in multiple views, which may appear in different locations within each page layout.
  • You have content in subviews which might which frequently change or might be subject to certain access controls, such as limiting access to users in certain roles.
  • You want to avoid directly embedding and duplicating subviews in multiple views which makes layout changes difficult to manage and maintain.

Solution

Use Composite Views that are composed of multiple atomic subviews. Each subview of the overall template can be included dynamically in the whole, and the layout of the page can be managed independently of the content.
For example, the portal sites that include numerous independent subviews, such as news feeds, weather information, and stock quotes on a single page. The layout of the page is managed and modified independently of the subview content.
Another benefit of this pattern is that web designers can prototype the layout of a site, plugging static content into each of the template regions. As site development progresses, the actual content is substituted for these placeholders. This approach provides improved modularity and reusability, as well as improved maintainability.

Structure

We used UML class diagram to show the basic structure of the solution and the UML Sequence diagram in this section present the dynamic mechanisms of the solution. 
Below is the class diagram representing the relationships for the Composite View Design Pattern.

Class diagram


Sequence Diagram


Participants and Responsibilities

Client - A Client dispatches to a View.
View - A View represents the display.
SimpleView - A SimpleView represents an atomic portion of a composite whole. It is also referred to as a view segment or subview.
CompositeView - A CompositeView is composed of multiple Views. Each of these Views is either a SimpleView or itself potentially a CompositeView.
Template - A Template represents the view layout.

How this pattern works

To understand this pattern, let's take an example. In the following picture, you can see a typical structure of a web page.
This structure is called "Classic Layout". The template organizes the page according to this layout, putting each "piece" in the needed place so that the header goes up, the footer down, etc.
It can happen that, for example clicking on a link, it is needed to change only a part of the page, typically the body.
As you can see, the pages are different, but their difference is only in the body part. Note that, however, the pages are distinct, it is not like a refresh of a frame in a frameset!
Using the composite view pattern, the other part of the page has been reused, and the layout consistence has been preserved.

Implementation

In this example, View management is implemented using standard JSP tags, such as the jsp:include tag. Using standard tags for managing the layout and composition of views is an easy strategy to implement.
Example for Standard Tag View Management Strategy :
<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>
Example of Apache Tiles Integration with Spring MVC
Apache Tiles is a free, open-source templating framework purely built on the Composite design pattern. In Apache Tiles, a page is built by assembling a composition of subviews called Tiles.
Step 1: Provide Dependency Configuration
<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-jsp</artifactId>
    <version>3.0.7</version>
</dependency>
Step 2:Define Tiles Layout Files
<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>
Step 3: ApplicationConfiguration and Other Classes
@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[] {
            "/"
        };
    }
}
Finally, in the ApplicationConfiguration class, we used TilesConfigurer and TilesViewResolver classes to achieve the integration:
@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/");
    }
}
Step 4: Tiles Template Files
<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>

Consequences

  • Improves modularity and reuse
  • Adds role-based or policy-based control
  • Enhances maintainability
  • Reduces maintainability
  • Reduces performance

Real world examples

References

Related Presentation Tier Posts

Comments