SlideShare una empresa de Scribd logo
1 de 21
Descargar para leer sin conexión
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?

Más contenido relacionado

La actualidad más candente

Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml Classes
Kaniska Mandal
 
GQL CheatSheet 1.1
GQL CheatSheet 1.1GQL CheatSheet 1.1
GQL CheatSheet 1.1
sones GmbH
 
GQL cheat sheet latest
GQL cheat sheet latestGQL cheat sheet latest
GQL cheat sheet latest
sones GmbH
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD Framework
Kaniska Mandal
 

La actualidad más candente (20)

Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
 
Mastering Oracle ADF Bindings
Mastering Oracle ADF BindingsMastering Oracle ADF Bindings
Mastering Oracle ADF Bindings
 
Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#
 
guice-servlet
guice-servletguice-servlet
guice-servlet
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
 
"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин
 
Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"
 
Specs2
Specs2Specs2
Specs2
 
Anton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightAnton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 light
 
Secret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you aboutSecret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you about
 
Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml Classes
 
GQL CheatSheet 1.1
GQL CheatSheet 1.1GQL CheatSheet 1.1
GQL CheatSheet 1.1
 
Con5623 pdf 5623_001
Con5623 pdf 5623_001Con5623 pdf 5623_001
Con5623 pdf 5623_001
 
Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con django
 
Clean Test Code
Clean Test CodeClean Test Code
Clean Test Code
 
JavaFX for Business Application Developers
JavaFX for Business Application DevelopersJavaFX for Business Application Developers
JavaFX for Business Application Developers
 
Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
GQL cheat sheet latest
GQL cheat sheet latestGQL cheat sheet latest
GQL cheat sheet latest
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD Framework
 

Similar a Mpg Dec07 Gian Lorenzetto

Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in production
Martijn Dashorst
 
Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
martinlippert
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片
cfc
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
Darwin Durand
 
Building Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And TricksBuilding Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And Tricks
Mike Hugo
 

Similar a Mpg Dec07 Gian Lorenzetto (20)

Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in production
 
Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片
 
Dependency Injection for Android
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
 
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
#JavaFX.forReal()
#JavaFX.forReal()#JavaFX.forReal()
#JavaFX.forReal()
 
Design patterns for fun and profit
Design patterns for fun and profitDesign patterns for fun and profit
Design patterns for fun and profit
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
Key Insights into Development Design Patterns for Magento 2 - Magento Live UK
Key Insights into Development Design Patterns for Magento 2 - Magento Live UKKey Insights into Development Design Patterns for Magento 2 - Magento Live UK
Key Insights into Development Design Patterns for Magento 2 - Magento Live UK
 
Building Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And TricksBuilding Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And Tricks
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Ordering System IP2buildclasses.netbeans_automatic_buildO.docx
Ordering System IP2buildclasses.netbeans_automatic_buildO.docxOrdering System IP2buildclasses.netbeans_automatic_buildO.docx
Ordering System IP2buildclasses.netbeans_automatic_buildO.docx
 
Practical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich ClientsPractical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich Clients
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 

Más de melbournepatterns

Abstract Factory Design Pattern
Abstract Factory Design PatternAbstract Factory Design Pattern
Abstract Factory Design Pattern
melbournepatterns
 

Más de melbournepatterns (20)

An Introduction to
An Introduction to An Introduction to
An Introduction to
 
State Pattern from GoF
State Pattern from GoFState Pattern from GoF
State Pattern from GoF
 
Iterator Pattern
Iterator PatternIterator Pattern
Iterator Pattern
 
Iterator
IteratorIterator
Iterator
 
Concurrency Patterns
Concurrency PatternsConcurrency Patterns
Concurrency Patterns
 
Continuous Integration, Fast Builds and Flot
Continuous Integration, Fast Builds and FlotContinuous Integration, Fast Builds and Flot
Continuous Integration, Fast Builds and Flot
 
Command Pattern
Command PatternCommand Pattern
Command Pattern
 
Code Contracts API In .Net
Code Contracts API In .NetCode Contracts API In .Net
Code Contracts API In .Net
 
LINQ/PLINQ
LINQ/PLINQLINQ/PLINQ
LINQ/PLINQ
 
Gpu Cuda
Gpu CudaGpu Cuda
Gpu Cuda
 
Facade Pattern
Facade PatternFacade Pattern
Facade Pattern
 
Phani Kumar - Decorator Pattern
Phani Kumar - Decorator PatternPhani Kumar - Decorator Pattern
Phani Kumar - Decorator Pattern
 
Composite Pattern
Composite PatternComposite Pattern
Composite Pattern
 
Adapter Design Pattern
Adapter Design PatternAdapter Design Pattern
Adapter Design Pattern
 
Prototype Design Pattern
Prototype Design PatternPrototype Design Pattern
Prototype Design Pattern
 
Factory Method Design Pattern
Factory Method Design PatternFactory Method Design Pattern
Factory Method Design Pattern
 
Abstract Factory Design Pattern
Abstract Factory Design PatternAbstract Factory Design Pattern
Abstract Factory Design Pattern
 
A Little Lisp
A Little LispA Little Lisp
A Little Lisp
 
State Pattern in Flex
State Pattern in FlexState Pattern in Flex
State Pattern in Flex
 
Active Object
Active ObjectActive Object
Active Object
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Último (20)

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 

Mpg Dec07 Gian Lorenzetto

  • 1. Encapsulate Composite with Builder Gian Lorenzetto
  • 2. Recap ... • Replace Implicit Tree with Composite (Refactoring to Patterns) • Refactoring to Composite loosens coupling to implicit tree • Builder loosens coupling to Composite
  • 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. 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. 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. 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. 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. TagNode Revisited Class Diagram 5_1196681761272 * Composite interface ~ Builder interface
  • 10. Step 1. Create Builder public class TagBuilderTest ... public void testBuilderOneNode() { String expectedXml = “<flavors/>”; String actualXml = TagBuilder(“flavors”).toXml(); assertXmlEquals(expectedXml, actualXml); }
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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”); ... }