Mpg Dec07 Gian Lorenzetto

454 views
418 views

Published on

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
454
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Mpg Dec07 Gian Lorenzetto

  1. 1. Encapsulate Composite with Builder Gian Lorenzetto
  2. 2. Recap ... • Replace Implicit Tree with Composite (Refactoring to Patterns) • Refactoring to Composite loosens coupling to implicit tree • Builder loosens coupling to Composite
  3. 3. Builder (Gof) BuilderDiagram_1196754930587
  4. 4. 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.
  5. 5. 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”); ...
  6. 6. 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());
  7. 7. • 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
  8. 8. 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
  9. 9. TagNode Revisited Class Diagram 5_1196681761272 * Composite interface ~ Builder interface
  10. 10. Step 1. Create Builder public class TagBuilderTest ... public void testBuilderOneNode() { String expectedXml = “<flavors/>”; String actualXml = TagBuilder(“flavors”).toXml(); assertXmlEquals(expectedXml, actualXml); }
  11. 11. Step 1. Create Builder public class TagBuilder { private TagNode rootNode; public TagBuilder(String rootTagName) { rootNode = new TagNode(rootTagName); } public String toXml() { return rootNode.toString(); } }
  12. 12. 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); }
  13. 13. 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); } ...
  14. 14. 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); }
  15. 15. 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?
  16. 16. 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); }
  17. 17. 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); } ...
  18. 18. 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() { ... } }
  19. 19. 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() { ... } }
  20. 20. 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”); ... }
  21. 21. Questions?

×