Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Builder Vs Decorator pattern [closed]

From When would you use the Builder Pattern?,

It is said that builder pattern is appropriate for Pizza example.

Why not Decorator ? by treating Cheese, Pepperoni, Bacon as additional decorations on a base pizza.

Is it for the reason that Cheese/Pepperoni have to be built seperately. I don't think, they need to be built seperately as they can be available readymade.

Pls clarify. Am also looking for a good real-world example of decorator pattern and reason why it is the apt for that particular example. Thank you.

like image 890
bjskishore123 Avatar asked Jan 22 '11 14:01

bjskishore123


People also ask

What is a disadvantage of the decorator pattern?

Disadvantages. High degree of flexibility. High complexity of software (especially decorator interface) Expansion of function of classes without inheritance.

When would you use a Builder design pattern?

The Builder Design Pattern helps us to slice the operations of building an object. It focuses on constructing a complex object step by step. It also enforces a process to create an object as a finished product.

What is the advantage of decorator pattern?

Advantage of Decorator PatternIt enhances the extensibility of the object, because changes are made by coding new classes. It simplifies the coding by allowing you to develop a series of functionality from targeted classes instead of coding all of the behavior into the object.


2 Answers

From wikipedia's decorator pattern article:

In object-oriented programming, the decorator pattern is a design pattern that allows new/additional behaviour to be added to an existing object dynamically.

There's no need to add toppings to a Pizza after it has been fully constructed. You don't eat half a pizza and then add another topping to it.

In other words, the Builder Pattern makes it easy to construct an object which is extensible in independent directions at construction time, while the Decorator Pattern lets you add extensions to functionality to an object after construction time. Using the decorator pattern to construct objects is bad because it leaves the object in an inconsistent (or at least incorrect) state until all the required decorators are in place - similar to the JavaBean problem of using setters to specify optional constructor arguments.

like image 107
Philip Potter Avatar answered Sep 24 '22 12:09

Philip Potter


You are confusing two very different things. GoF classifies Builder as a creational pattern, while Decorator is a structural pattern. They are described as follows (Gamma et al, page 1):

Builder (97) Separate the construction of a complex object from its representation so that the same construction process can create different representations.

Decorator (175) Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Note the emphasis on the decorator. It's a flexible alternative to subclassing. Subclassing is used to model an is-a relationship. Cheese is not a pizza. The pizza is composed of a number of ingredients, and that is usually modeled using composition.

The builder pattern is relevant here because there are such a vast number of ingredients that the need arises to construct them in a standardized way.

To take a real world example of a decorator, I recently wanted to log the queries executed using jdbc in my java application. I accomplished this by implementing a class called LoggingConnection which extended the Connection interface.

public class LoggingConnection implements Connection {     public static class LogEntry     {         public String sql;         public int invocationCount;         public double avgTime;         public double maxTime;     }      private Connection delegate;      private Map<String, LogEntry> log;      public LoggingConnection(Connection delegate)     {         this.delegate = delegate;         this.log = new HashMap<String, LogEntry>();     }      public Map<String, LogEntry> getLog()     {         return log;     }      @Override     public void clearWarnings()     throws SQLException     {         delegate.clearWarnings();     }      @Override     public void close()     throws SQLException     {         delegate.close();     }      // forwarding declarations to all other methods declared in the interface     ... } 

This allows me to pass a concrete implemention of a connection, and extend its functionality at runtime. Subclassing would be problematic in this context, because you don't necessarily know what connection object is actually returned. This is because it's constructed for you using the DriverManager factory:

Connection conn = DriverManger.getConnection(dsn); 

The conn object is in this case an implementation contained in the driver, which I generelly don't know the name of. The beuty of the decorator approach is that I don't have to know, and that it isn't tied to a specific implementation.

like image 39
Emil H Avatar answered Sep 24 '22 12:09

Emil H