Sunday, July 12, 2015

The Builder Pattern - GOF



The Builder Pattern separates the construction of a complex object from its representation so that the same construction process can create different representations. - Gof
Builder pattern is used to construct a complex object step by step and the final step will return the object. The process of constructing an object should be generic so that it can be used to create different representations of the same object.

With the builder pattern, the same object construction process can be used to create different objects.

https://en.wikipedia.org/wiki/Builder_pattern
Unlike the abstract factory pattern and the factory method patternwhose intention is to enable polymorphism, the intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern

The telescoping constructor anti-pattern occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once.

Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract FactoryPrototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed. Sometimes creational patterns are complementary: Builder can use one of the other patterns to implement which components are built. Builders are good candidates for a fluent interface.

The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.

Builder Structure
https://dzone.com/articles/design-pattern-builder-pattern


  • The Director object is responsible for the construction process of the complex object but delegates the actual creation and assembly to the Builder interface.
  • The Builder object specifies the interface for creating parts of the complex object.
  • The Product represents the complex object that is created by the ConcreteBuilderobjects. The Product consists of multiple parts that are created separately by theConcreteBuilder objects.
  • The ConcreteBuilder objects create and assemble the parts that make up theProduct through the Builder interface.

  • A client object creates an instance of the Director object and passes it the appropriate Builder object. The Director object invokes the methods on the Builder object to create and initialize specific parts of the Product object. The Builder receives content from the Director object and adds these to the Product object. The Client object has a reference to the Builder object and retrieves the created Product object from it.
    Difference between Builder and Factory
    Builder pattern is used when there are many steps to create an object. Factory pattern is used when the factory can easily create the entire object within one method call.

    In builder pattern emphasis is on ‘step by step’. Builder pattern will have many number of small steps. Those every steps will have small units of logic enclosed in it. There will also be a sequence involved. It will start from step 1 and will go on upto step n and the final step is returning the object. In these steps, every step will add some value in construction of the object. That is you can imagine that the object grows stage by stage. Builder will return the object in last step. But in abstract factory how complex the built object might be, it will not have step by step object construction.

    How about template pattern?
    Sample builder design pattern implementation in Java API
    DocumentBuilderFactory , StringBuffer, StringBuilder are some examples of builder pattern usage in java API.
    Does StringBuilder utilize the Builder pattern? -- No

    Example: 
    https://github.com/mission-peace/EffectiveJava/blob/master/src/com/ej/builder/Order.java
    public class Order {

        private final String orderId;
        private final String customerId;
        private final int orderPrice;
        private final Date orderDate;
       
        public static class Builder{
            private String orderId;
            private String customerId;
            private int orderPrice;
            private Date orderDate;
           
            public Builder(String orderId, String customerId){
                this.orderId = orderId;
                this.customerId = customerId;
            }
           
            public Builder orderPrice(int orderPrice){
                this.orderPrice = orderPrice;
                return this;
            }
           
            public Builder orderDate(Date orderDate){
                this.orderDate = orderDate;
                return this;
            }
           
            public Order build(){
                return new Order(orderId, customerId, orderPrice, orderDate);
            }
        }
       
        private Order(String orderId, String customerId, int orderPrice, Date orderDate){
            this.orderId = orderId;
            this.customerId = customerId;
            this.orderPrice = orderPrice;
            this.orderDate = orderDate;
        }
       
        public static void main(String args[]){
            Order.Builder builder = new Order.Builder("2131", "1515");
            Order order = builder.orderPrice(10).orderDate(new Date()).build();
        }
    }

    http://javapapers.com/design-patterns/builder-pattern/
      HouseBuilder iglooBuilder = new IglooHouseBuilder();
      CivilEngineer engineer = new CivilEngineer(iglooBuilder);
      engineer.constructHouse();
      House house = engineer.getHouse();
    public class CivilEngineer {
    
     private HouseBuilder houseBuilder;
    
     public CivilEngineer(HouseBuilder houseBuilder){
      this.houseBuilder = houseBuilder;
     }
    
     public House getHouse() {
      return this.houseBuilder.getHouse();
     }
    
     public void constructHouse() {
      this.houseBuilder.buildBasement();
      this.houseBuilder.buildStructure();
      this.houseBuilder.bulidRoof();
      this.houseBuilder.buildInterior();
     }
    }
    public class TipiHouseBuilder implements HouseBuilder {
     private House house; //should use Interface HousePlan?
    
     public TipiHouseBuilder() {
      this.house = new House();
     }
    
     public void buildBasement() {
      house.setBasement("Wooden Poles");
     }
    
     public void buildStructure() {
      house.setStructure("Wood and Ice");
     }
    
     public void buildInterior() {
      house.setInterior("Fire Wood");
     }
    
     public void bulidRoof() {
      house.setRoof("Wood, caribou and seal skins");
     }
    
     public House getHouse() {
      return this.house;
     }
    
    }
    public class House implements HousePlan {
    
     private String basement;
     private String structure;
     private String roof;
     private String interior;
    
     public void setBasement(String basement) {
      this.basement = basement;
     }
    
     public void setStructure(String structure) {
      this.structure = structure;
     }
    
     public void setRoof(String roof) {
      this.roof = roof;
     }
    
     public void setInterior(String interior) {
      this.interior = interior;
    
     }
    
    }
    X. Builder to replace complex constructor.
    http://jlordiales.me/2012/12/13/the-builder-pattern-in-practice/
    he first issue has to do with having an instance of this class in an inconsistent state.
    The second disadvantage of this approach is that now the User class is mutable. You’re loosing all the benefits of immutable objects.
    public User getUser() {
      return new
        User.UserBuilder("Jhon", "Doe")
        .age(30)
        .phone("1234567")
        .address("Fake address 1234")
        .build();

    }
    • The User constructor is private, which means that this class can not be directly instantiated from the client code.
    • The class is once again immutable. All attributes are final and they’re set on the constructor. Additionally, we only provide getters for them.
    • The builder uses the Fluent Interface idiom to make the client code more readable (we’ll see an example of this in a moment).
    • The builder constructor only receives the required attributes and this attributes are the only ones that are defined “final” on the builder to ensure that their values are set on the constructor.
    you’re making sure that whenever you get an object of this class is not going to be on an incomplete state.
    The builder could even auto-complete some generated field between each invocation, such as an id or serial number.

    An important point is that, like a constructor, a builder can impose invariants on its parameters. The build method can check these invariants and throw an IllegalStateExceptionif they are not valid.

    It is critical that they be checked after copying the parameters from the builder to the object, and that they be checked on the object fields rather than the builder fields. The reason for this is that, since the builder is not thread-safe, if we check the parameters before actually creating the object their values can be changed by another thread between the time the parameters are checked and the time they are copied. This period of time is known as the “window of vulnerability”. 
    public User build() {
      User user = new user(this);
      if (user.getAge() > 120) {
        throw new IllegalStateException(“Age out of range”); // thread-safe
      }
      return user;
    }
    // bad
    public User build() {
      if (age > 120) {
        throw new IllegalStateException(“Age out of range”); // bad, not thread-safe
      }
      // This is the window of opportunity for a second thread to modify the value of age
      return new User(this);
    }

    given the fact that the builder class is usually a static member class of the class it builds, they can evolve together fairly easy.

    http://www.journaldev.com/1425/builder-design-pattern-in-java
    large number of parameters by providing a constructor with required parameters and then different setter methods to set the optional parameters but the problem with this is that the Object state will be inconsistent until unless all the attributes are set explicitly.

    Builder pattern solves the issue with large number of optional parameters and inconsistent state by providing a way to build the object step-by-step and provide a method that will actually return the final Object.
    Computer class has only getter methods and no public constructor, so the only way to get a Computer object is through the ComputerBuilder class.
    public class Computer
        //required parameters
        private String HDD;
        private String RAM;
        //optional parameters
        private boolean isGraphicsCardEnabled;
        private boolean isBluetoothEnabled;
        public String getHDD()
        public String getRAM()
        public boolean isGraphicsCardEnabled()
        public boolean isBluetoothEnabled()
        private Computer(ComputerBuilder builder) {
            this.HDD=builder.HDD;
            this.RAM=builder.RAM;
            this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
            this.isBluetoothEnabled=builder.isBluetoothEnabled;
        }
        //Builder Class
        public static class ComputerBuilder{
            // required parameters
            private String HDD;
            private String RAM;
            // optional parameters
            private boolean isGraphicsCardEnabled;
            private boolean isBluetoothEnabled;
             
            public ComputerBuilder(String hdd, String ram){
                this.HDD=hdd;
                this.RAM=ram;
            }
            public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
                this.isGraphicsCardEnabled = isGraphicsCardEnabled;
                return this;
            }
            public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
                this.isBluetoothEnabled = isBluetoothEnabled;
                return this;
            }
             
            public Computer build(){
                return new Computer(this);
            }
        }
    }
            Computer comp = new Computer.ComputerBuilder(
                    "500 GB", "2 GB").setBluetoothEnabled(true)
                    .setGraphicsCardEnabled(true).build();
    http://www.avajava.com/tutorials/lessons/builder-pattern.html
    MealBuilder
    ItalianMealBuilder
    Product: Meal
    MealDirector
    http://www.codeproject.com/Articles/42415/Builder-Design-Pattern
    Kid build Animal.
    http://javarevisited.blogspot.com/2012/06/builder-design-pattern-in-java-example.html
    Advantages:
    1) more maintainable if number of fields required to create object is more than 4 or 5.
    2) less error-prone as user will know what they are passing because of explicit method call.
    3) more robust as only fully constructed object will be available to client.

    Disadvantages:
    1) verbose and code duplication as Builder needs to copy all fields from Original or Item class.
    UPDATE: if you use Eclipse as your IDE, it turns out that you have quite a few plugins to avoid most of the boiler plate code that comes with the pattern. The three I’ve seen are:
    https://sourcemaking.com/design_patterns/builder
    Too Many Parameters in Java Methods, Part 3: Builder Pattern
    http://www.javaworld.com/article/2074938/core-java/too-many-parameters-in-java-methods-part-3-builder-pattern.html
    http://www.oodesign.com/builder-pattern.html

    Labels

    Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

    Popular Posts