Mpg Dec07 Gian Lorenzetto
Upcoming SlideShare
Loading in...5
×
 

Mpg Dec07 Gian Lorenzetto

on

  • 582 views

 

Statistics

Views

Total Views
582
Views on SlideShare
571
Embed Views
11

Actions

Likes
0
Downloads
3
Comments
0

2 Embeds 11

http://melbournepatterns.org 10
http://melbournepatterns.wordpress.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Mpg Dec07 Gian Lorenzetto Mpg Dec07 Gian Lorenzetto Presentation Transcript

  • Encapsulate Composite with Builder Gian Lorenzetto
  • Recap ... • Replace Implicit Tree with Composite (Refactoring to Patterns) • Refactoring to Composite loosens coupling to implicit tree • Builder loosens coupling to Composite
  • Builder (Gof) BuilderDiagram_1196754930587
  • Builder (GoF) • The construction of a complex object is separated from its representation so that the same construction process can create different representations • Builder Defines the required operations for creating various parts of a product • ConcreteBuilder Implements the operations declared in the Builder interface. • Director Builds a specific product via the interface exposed by the Builder object. • Product The concrete type the Builder object creates.
  • Class Diagram 1_1196587101774 TagNode activityTag = new TagNode(“activity”); ... TagNode flavorsTag = new TagNode(“flavors”); activityTag.add(favorsTag); ... TagNode flavorTag = new TagNode(“flavor”); flavorsTag.add(flavorTag); Class Diagram 3_1196677789548 TagBuilder builder = new TagBuilder(“activity”); ... builder.addChild(“flavors”); ... builder.addToParent(“flavors”, “flavor”); ...
  • Class Diagram 2_1196596929958 Document doc = new DocumentImpl(); Element orderTag = doc.createElement(“order”); orderTag.setAttribute(“id”, order.getOrderId()); Element productTag = doc.createElement(“product”); productTag.setAttribute(“id”, product.getID()); Text productName = doc.createTextNode(product.getName()); productTag.appendChild(productName); orderTag.appendChld(productTag); Class Diagram 4_1196679481681 DOMBuilder orderBuilder = new DOMBuilder(“order”) orderBuilder.addAttribute(“id”, order.getOrder()); orderBuilder.addChild(“product”); orderBuilder.addAttribute(“id”, product.getID()); orderBuilder.adValue(product.getName());
  • • Benefits Simplifies a client’s code for constructing a Composite Reduces the repetitive and error-prone nature of Composite creation Creates a loose coupling between client and Composite Allows for different representations of the encapsulated Composite or complex object • Liabilities May not have the most intention-revealing interface
  • Mechanics 1. Create Builder 2. Make Builder capable of creating children 3. Make Builder capable of setting attributes on nodes 4. Reflect on interface ... simplify 5. Refactor Composite construction code to use Builder
  • TagNode Revisited Class Diagram 5_1196681761272 * Composite interface ~ Builder interface
  • Step 1. Create Builder public class TagBuilderTest ... public void testBuilderOneNode() { String expectedXml = “<flavors/>”; String actualXml = TagBuilder(“flavors”).toXml(); assertXmlEquals(expectedXml, actualXml); }
  • Step 1. Create Builder public class TagBuilder { private TagNode rootNode; public TagBuilder(String rootTagName) { rootNode = new TagNode(rootTagName); } public String toXml() { return rootNode.toString(); } }
  • Step 2. Support child creation and placement public class TagBuilderTest ... public void testBuilderOneChild() { String expectedXml = “<flavors>” + “<flavor/>” + “</flavors>”; TagBuilder builder = TagBuilder(“flavors”); builder.addChild(“flavor”); String actualXml = builder.toXml(); assertXmlEquals(expectedXml, actualXml); }
  • Step 2. Support child creation and placement public class TagBuilder { private TagNode rootNode; private TagNode currentNode; public TagBuilder(String rootTagName) { rootNode = new TagNode(rootTagName); currentNode = rootNode; } pubic void addChild(String childTagName) { TagNode parentNode = currentNode; currentNode = new TagNode(childTagName); parentNode.addChild(curentNode); } ...
  • Step 2. Support child creation and placement public class TagBuilderTest ... public void testBuilderOneChild() { String expectedXml = “<flavors>” + “<flavor1/>” + “<flavor2/>” + “</flavors>”; TagBuilder builder = TagBuilder(“flavors”); builder.addChild(“flavor1”); builder.addSibling(“flavor2”); String actualXml = builder.toXml(); assertXmlEquals(expectedXml, actualXml); }
  • Step 2. Support child creation and placement public class TagBuilder ... pubic void addChild(String childTagName) { addTo(currentNode, childTagName); } public void addSibling(String siblingTagName) { addTo(currentNode.getParent(), siblingTagName); } private void addTo(TagNode parentNode, String tagName) { currentNode = new TagNode(tagName); parentNode.addChild(curentNode); } ... 1. Refactor Composite to support Builder 2. Thirdparty Composite?
  • Step 3. Support attributes and values public class TagBuilderTest ... public void testAttributesAndVaues() { String expectedXml = “<flavor name=ʼTest-Driven Developmentʼ>” + “<requirements>” + “<requirement type=ʼhardwareʼ>” + “1 computer for every 2 participants” + “</requirement>” “</requirements>” + “</flavor>”; TagBuilder builder = TagBuilder(“flavor”); builder.addAttribute(“name”, “Test-Driven Development”); builder.addChild(“requirements”); builder.addToParent(“requirements”, “requirement”); builder.addAttribute(“type”, “hardware”); builder.addValue(“1 computer for every 2 participants”); String actualXml = builder.toXml(); assertXmlEquals(expectedXml, actualXml); }
  • Step 3. Support attributes and values public class TagBuilder ... pubic void addAttribute(String name, String value) { currentNode.addAttribute(name, value); } public void addValue(String value) { currentNode.addValue(value); } ...
  • Step 4. Reflect ... public class TagBuilder { public TagBuilder(String rootTagName) { ... } public void addChild(String childTagName) { ... } public void addSibling(String siblingTagName) { ... } public void addToParent(String parentTagName, String childTagName) { ... } public void addAttribute(String name, String value) { ... } public void addValue(String value) { ... } public String toXml() { ... } }
  • public class TagBuilder { public TagBuilder(String rootTagName) { ... } public void addChild(String childTagName) { ... } public void addSibling(String siblingTagName) { ... } public void addToParent(String parentTagName, String childTagName) { ... } public void addAttribute(String name, String value); public void addValue(String value); public String toXml() { ... } } public class TagNode { public TagNode(String tagName) { ... } public void add(TagNode childNode) { ... } public void addAttribute(String name, String value) { ... } public void addValue(String value) { ... } public String toString() { ... } }
  • Step 5. Replace Composite construction code public class CatalogWriter ... TagNode requirementsTag = new TagNode(“requirements”); flavorTag.add(requirementsTag); for (int i = 0; i < requirementsCount; ++i) { Requirement requirement = flavor.getRequirements()[i]; TagNode requirementTag = new TagNode(“requirement”); ... requirementsTag.add(requirementsTag); } public class CatalogWriter ... builder.addChild(“requirements”); for (int i = 0; i < requirementsCount; ++i) { Requirement requirement = flavor.getRequirements()[i]; builder.addToParent(“requirements”, “requirement”); ... }
  • Questions?