0% found this document useful (0 votes)
7 views

OOAD Builder Pattern

The document discusses various design patterns in object-oriented programming, focusing on the Builder Pattern, which separates the construction of complex objects from their representation. It outlines the importance of factories in managing object creation and emphasizes the need for separation of concerns to enhance code cohesion. Additionally, it provides examples of Builder implementation in Java, demonstrating how to create objects in a flexible and readable manner.

Uploaded by

yatharthis0031
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

OOAD Builder Pattern

The document discusses various design patterns in object-oriented programming, focusing on the Builder Pattern, which separates the construction of complex objects from their representation. It outlines the importance of factories in managing object creation and emphasizes the need for separation of concerns to enhance code cohesion. Additionally, it provides examples of Builder implementation in Java, demonstrating how to create objects in a flexible and readable manner.

Uploaded by

yatharthis0031
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Builder Patterns

CSCI 4448/5448: Object-Oriented Analysis & Design

1

Pattern Classification
• The Gang of Four Core Four classified patterns in three ways
• The behavioral patterns are used to manage variation in behaviors, interaction,
and distribution of responsibility
• The structural patterns are useful to compose classes or objects in larger
structures
• The creational patterns are used to create objects and decouple clients from
instantiations

2
Pattern Classification
• Are the patterns related to Classes or Objects?

3
Pattern Libraries & Documenting Patterns

• Name – Identifies the pattern


• Classification – Category of pattern
• Intent – Short form of what pattern does
• Motivation – Scenario with problem and solution
• Applicability – Situations to use the pattern
• Structure – UML diagram showing relationships
• Participants – Classes/objects in design
• Collaborations – How participants work together
• Consequences – Any good/bad effects from using the pattern
• Implementation/Sample Code – How to use it
• Known Uses – Examples in real systems
• Related Patterns – How this pattern relates to others
Factories & Their Role in OO Design

• It is important to manage the creation of objects


• Code that mixes object creation with the use of objects can become quickly non-
cohesive
• A system may have to deal with a variety of different contexts and with each context
requiring a different set of objects
• The code to determine the current context, and thus which objects to
instantiate, can become complex with many different conditional statements.
• When we see this, it is a signal to us that refactoring might be in order and perhaps
we should use a Factory pattern.

5
Factories & Their Role in OO Design

• If you mix this type of code with the use of the instantiated objects, your
code becomes cluttered with responsibilities
• often the use scenarios can happen in a few lines of code
• if combined with creational code, the operational code gets buried behind the
creational code
• Similar issues arise when mixing user interface creation and
management with underlying business logic or data handling
• One of the reasons for MVC, for instance

• Separation of concerns — increases cohesiveness


• Single responsibility — easy to understand, easier to reuse

6
Factories provide Cohesion

• The conditional code can be hidden within them


• Pass in the parameters associated with the current context
• Get back the objects you need for the situation
• Use those objects to get your work done

7
The Object Creation/Management Rule
An object should either:
• create/manage a set of objects OR
• use other objects
• But as a guideline, the rule is useful
• Look for ways to separate out the creation of objects from the code that makes use of
those objects
• encapsulate the creation process and you can change it as needed without impacting the code that
then uses those objects
• Demonstration of the advantages of the rule are in the following two diagrams

8
Client Perspective

9
Factory Perspective

10
Factories help to limit change

• If a change request relates to the creation of an object, the change will


likely occur in a factory
• all client code will should remain unaffected
• If a change request does not relate to the creation of objects, the change
will likely occur in the use of an object or the features it provides
• your factories can be ignored as you work to implement the change

11
Polymorphic Factory Thoughts

• What if we wanted to make some of our Rooms MagicRooms?


• What has to change in our Polymorphia game?
• If we were creating Room objects, that will need to change and to
expand.
• But if we aren’t creating new Room objects we could be passed a maze
with MagicRooms and we wouldn’t even know the difference…as long as
what is true?
• MagicRoom is-a Room, meaning it has the same interface.
• Maybe a magic room creates extra food randomly
• But wouldn’t the room then be doing: new Food(“hot pocket”) ?
• Not if the MagicRoom was passed a FoodFactory when it was created:
• foods.append(foodFactory.createFoodItem(“hot pocket”))
Factory Patterns

• Simple Factory: Isolate instantiation in a single purpose class


• Factory Method: Pizza and Pizza Store example
• Have client code use an abstract method that returns a needed instance of an interface
• Have a subclass implementation determine the concrete implementation that is returned
• Abstract Factory: Pizza Ingredients Example
• Pattern that creates groups or families of related objects

13
Builder Pattern Overview

• Intent:
• Separate the construction of a complex object from its representation so that
the same construction process can create different representations
• Eliminate the telescoping constructor problem of n * m different constructor
methods
• Use when:
• the algorithm for creating a complex object should be independent of the parts
that make up the object and how they’re assembled
• the construction process must allow different representations for the object
that’s constructed
• the construction of a product is complex and we want toallow it to be
constructed in steps

14
Telescoping Constructors
public Maze() {}

public Maze(List<Room> rooms) {}

public Maze(List<Room> rooms, List<Adventurer> adventurers) {}

public Maze(Integer numRooms) {}

public Maze(Integer numRooms, Integer numAdventurers) {}

public Maze(Integer numRooms, Integer numAdventurers, AdventurerFactory adventurerFactory) {}

public Maze(Integer numRooms, Integer numAdventurers, Integer numCreatures) {}

public Maze(Integer numRooms, Integer numAdventurers, Integer numCreatures, Integer numFoodItems) {}

public Maze(Integer numRooms, Integer numAdventurers, Integer numCreatures, Integer numFoodItems,

ConnectionStrategy strategy) {}

public Maze(Integer numRooms, Integer numAdventurers, Integer numCreatures, Integer numFoodItems,

ConnectionStrategy strategy, DistributionStrategy adventureDistribution) {}

etc…
Android Dialog Example Usage
Inner class

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder
.setMessage("Do you want to cancel the download?”)
.setTitle("Cancel Download?")
.setNegativeButton("No!", ...)
.setPositiveButton("YES!", …);

return builder.create();

return new AlertDialog.Builder(this)


.setMessage("Do you want to cancel the download?”)
.setTitle("Cancel Download?");
.setNegativeButton("No!", ...);
.setPositiveButton("YES!", …);
.create();

16
In the Android example this
could be the Main app Builder UML Diagram
class method

AlertDialog.Builder

• A Director interacts with a


Builder to guide the creation of
a Product
• The Client creates the Director
and a specific Builder and then
asks the Director to create the
In the Android example this Product
could be the Main app • The Client retrieves the
class method Product directly from the
ConcreteBuilder

AlertDialog Box

17
What about Polymorphia?
What about this?

Maze.Builder

Polymorphia or Game class Maze

18
Builder in Head First: Vacation Schedule
Vacation Schedule UML

Remember the rule about


No Single Instance
Abstractions
Inner Classes
public class ContainingClass {
private String name = "ContainingClass";
private String uniqueName = "UniqueContainingClass";
private Integer id = 123;

public ContainingClass() {
System.out.println("ContainingClass constructor");
id = 246;
}

InnerClass createInnerClass() { ContainingClass containingClass = new ContainingClass();


return new InnerClass();
} ContainingClass.InnerClass innerClass = containingClass.createInnerClass();

class InnerClass {
String name = “InnerClass";

public void setContainingClassPrivateName(String name) {


ContainingClass.this.name = name;
}
Static Inner Classes
public class ContainingClass {
private String name = "ContainingClass";
private String uniqueName = "UniqueContainingClass";
private Integer id = 123;

public ContainingClass() {
System.out.println("ContainingClass constructor");
id = 246;
}

InnerClass createInnerClass() {
return new InnerClass();
}
ContainingClass.InnerClass innerClass = new ContainingClass.StaticInnerClass();

public static class StaticInnerClass {


String name = "StaticInnerClass";

}
}

No containing class
pointer here in the static
inner class
Inner Class Builder Example
public class BankAccount { Can access the private
public static class Builder { Builder is an inner class instance variables since
// This is important, so we'll pass it to the constructor Builder is an inner class
private long accountNumber;
private String owner;
private String branch;
private double balance; Returning the builder each
private double interestRate; Return fully initialized,
time creates a “fluent
consistent object
public Builder(long accountNumber) { interface”
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner) {
this.owner = owner;
return this; public BankAccount build(){
} BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
public Builder atBranch(String branch) { account.owner = this.owner;
this.branch = branch; account.branch = this.branch;
return this; account.balance = this.balance;
} account.interestRate = this.interestRate;
return account;
public Builder openingBalance(double balance) { }
this.balance = balance; }
return this;
} //Fields omitted for brevity.
BankAccount
constructor is private BankAccount() {
Duplicate instance variables private // probably doesn’t do much
of BankAccount? }
//Getters and setters omitted for brevity.
}

https://dzone.com/articles/design-patterns-the-builder-pattern
Inner Class Builder Example 2
public class BankAccount { just create the final object
initially
//Bank account fields omitted for brevity.
public static class Builder {
private BankAccount account = new BankAccount();

public Builder(long accountNumber) { Maybe use reasonable


account.accountNumber = accountNumber; defaults in the Builder
account.interestRate = DEFAULT_RATE; constructor?

}
public Builder withOwner(String owner) {
account.owner = owner; Then just set the values Or put the defaults in the
return this; directly on the object being build method where you
}
built. check for consistency
public Builder atBranch(String branch) {
accounts.branch = branch;
return this;
}
public Builder openingBalance(double balance) {
account.balance = balance;
return this;
}
… …
public BankAccount build(){
// Checks for consistency…
return account;
}
}
Example Builder Usage This argument better be
special — meaning
required for a valid
BankAccount

BankAccount account = new BankAccount.Builder(1234L)


.withOwner("Marge")
.atBranch("Springfield")
.openingBalance(100)
.atRate(2.5)
.build();
BankAccount anotherAccount = new BankAccount.Builder(4567L)
.withOwner("Homer")
.atBranch("Springfield")
.openingBalance(100)
.atRate(2.5)
.build();

Python example: https://refactoring.guru/design-patterns/builder/python/example


StringBuilder example
StringBuilder messageBuilder = new StringBuilder("Error:");

messageBuilder.append("More information. ");

messageBuilder.append("Error code: ");

messageBuilder.append(errorCode); What does the append()


method return?
System.out.println(messageBuilder);

StringBuilder messageBuilder = new StringBuilder(“Error:")


What happens here?
.append("More information. “)

.append(“Error code: ");

.append(errorCode);

System.out.println(messageBuilder);
HttpRequest example
void testHttpRequestGeneration2() {
HttpRequest request = new HttpRequest(uri,
listOfHeaders?,
timeOut, Lots of
action, arguments to the
body, constructor?
...
)
}

void testHttpRequestGeneration2() {
HttpRequest request = new HttpRequest(Map.of(
“header”: header,
“timeOut”: timeOut, One Map
“action”: action, argument?
“body”: body,
...
))
}
HttpRequest example
@Test
void testHttpRequestGeneration2() {
HttpRequest request = new HttpRequest();
request.setUri(uri);
request.addHeader("Content-Type", "text/plain;charset=UTF-8");
request.setAction(HttpActions.POST);
request.setBody(body);
request.setTimeout(myTimeOut);
...
}

Using public setters?

What about encapsulation?

Or mutation to an invalid state?


HttpRequest example This method can ensure a
valid object is made, either
by throwing
What an exception
about this one?
or relying on reasonable
@Test defaults
void testHttpRequestGeneration() {
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://postman-echo.com/post"))
.headers("Content-Type", "text/plain;charset=UTF-8")
.POST(HttpRequest.BodyPublishers.ofFile(
Paths.get("src/test/resources/sample.txt")))
.build();

public static HttpRequest.Builder newBuilder() {


return new HttpRequestBuilderImpl();
}

This name signals that the


Builder is an interface,
What’s this? A What type of object do otherwise we wouldn’t
concrete class? these methods return? need “Impl”

You might also like