Gang of Four Structural pattern: Composite
Structural Pattern
A tree structure of simple and composite objects. Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
Has a tree like structure of simple and composite objects. A Composite object can itself hold composite objects as well as simple objects.
To get the code for this example:
git clone https://github.com/spotadev/gangoffour.git
In src/main/java navigate to this package:
com.javaspeak.designpatterns.go4.structural.composite
You can run the code from the main method of:
CompositeApplication
In this example the composite objects are modelling html tables while the simple objects are modelling text. This example is not too disimilar to the apache tiles framework. The apache tile framework uses the composite framework.
package com.javaspeak.designpatterns.go4.structural.composite;
/**
* Text book description:
* <ul>
* Composite: A tree structure of simple and composite objects. Compose objects into tree
* structures to represent part-whole hierarchies. Composite lets clients treat individual
* objects and compositions of objects uniformly.
* </ul>
* Has a tree like structure of simple and composite objects. A Composite object can itself hold
* composite objects as well as simple objects.
* <p>
* In this example the composite objects are modelling html tables while the simple objects are
* modelling text. This example is not too disimilar to the apache tiles framework. The apache
* tile framework uses the composite framework.
*
* @author John Dickerson - 22 Feb 2020
*/
public class CompositeApplication {
/**
* Shows a web page made up of tables containing text and other tables.
*/
public void showWebPage() {
HtmlElement pageTableElement = new TableElement();
pageTableElement.getHtmlElements().add( new TextElement( "Composite Pattern" ) );
HtmlElement bodyTableElement = new TableElement();
bodyTableElement.getHtmlElements().add( new TextElement( "Hello" ) );
bodyTableElement.getHtmlElements().add( new TextElement( "World!" ) );
pageTableElement.getHtmlElements().add( bodyTableElement );
pageTableElement.getHtmlElements().add( new TextElement( "Footer & Copyright" ) );
StringBuilder htmlSb = new StringBuilder();
htmlSb.append( "<html>\n" );
htmlSb.append( "<head><title>Composite Pattern</title></head>\n" );
htmlSb.append( "<body>\n" );
htmlSb.append( pageTableElement.getHtml() );
htmlSb.append( "</body>" );
htmlSb.append( "</html>" );
System.out.println( htmlSb.toString() );
}
public static void main( String[] args ) {
CompositeApplication applicationComposite = new CompositeApplication();
applicationComposite.showWebPage();
}
}
package com.javaspeak.designpatterns.go4.structural.composite;
import java.util.List;
/**
* Used to define the structure of composite and simple elements.
* <p>
* AbstractHtmlElement provides an implementation for getHtmlElements() but leaves getHtml() to be
* implemented by parent classes. Both TextElement and HtmlElement extend AbstractHtmlElement and
* provide an implementation for getHtml() method. HtmlElement is a composite element which can
* itself be comprised of composite elements while TextElement is simple. TextElement is simple
* as it does not make use of getHtmlElements() in its getHtml() method.
*
* @author John Dickerson - 24 Feb 2020
*/
public interface HtmlElement {
/**
* Returns a list of HtmlElement. The calling code can call this method and a HtmlElement to
* the end of the list
*
* @return List of HtmlElement
*/
public List<HtmlElement> getHtmlElements();
/**
* Returns the Html. If the HtmlElement is a simple element it will not be using the
* List<HtmlElement>, however if it is a composite element it will iterate through the child
* HtmlElements and call getHtml() on each of them while building up the html to return.
*
* @return Html
*/
public String getHtml();
}
package com.javaspeak.designpatterns.go4.structural.composite;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract class that implements HtmlElement to provide functionality for the getHtmlElements()
* method. Does not implement getHtml(). Both TableElement and TextElement extend
* AbstractHtmlElement. The reason TextElement extends AbstractHtmlElement is that a sub class of
* TextElement may wish to become composite and make use of the list of <HtmlElement>. For example
* a more sophisticated implementation of TextElement may wish to include elements such as "bold"
* and "underline".
*
* @author John Dickerson - 24 Feb 2020
*/
public abstract class AbstractHtmlElement implements HtmlElement {
List<HtmlElement> htmlElements = new ArrayList<HtmlElement>();
@Override
public List<HtmlElement> getHtmlElements() {
return htmlElements;
}
@Override
public abstract String getHtml();
}
package com.javaspeak.designpatterns.go4.structural.composite;
/**
* Extends AbstractHtmlElement to provide a composite implementation for a Html table. An html
* table is considered a composite object as it can itself contain composite objects such as other
* html tables.
* <p>
* TableElement wraps the child HtmlElements in "tr" and "td" html tags.
*
* @author John Dickerson - 24 Feb 2020
*/
public class TableElement extends AbstractHtmlElement {
@Override
public String getHtml() {
if ( htmlElements != null ) {
StringBuilder sb = new StringBuilder();
sb.append( "<table cellspacing=\"5\" cellpadding=\"5\">\n" );
for ( HtmlElement pageElement : htmlElements ) {
sb.append( "<tr><td>" );
sb.append( pageElement.getHtml() ).append( "</td></tr>\n" );
}
sb.append( "</table>\n" );
return sb.toString();
}
return "";
}
}
package com.javaspeak.designpatterns.go4.structural.composite;
/**
* TextElement extends AbstractHtmlElement to provide a simple element implementation. TextElement
* does not make use of its List<HtmlElement>. It returns some simple text in its getHtml() method.
*
* @author John Dickerson - 24 Feb 2020
*
*/
public class TextElement extends AbstractHtmlElement {
private String text;
public TextElement( String text ) {
this.text = text;
}
@Override
public String getHtml() {
return this.text;
}
}
Back: Gang of Four
Page Author: JD