Aside: Design Pattern: Composite, Builder, Bridge, State and static Factory

Assignment 2 for my Design Pattern Course

Question 1)

Basics of Composite Pattern:

Composite is a pattern intended to Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
[DP, Gof]

Below is the example of composite taken from [DP, Gof]
Many simple Graphics objects form the together more complex objects. For example, a Picture is composition of a Text, a Line and a Rectangle, where this picture is further a part of another Picture.

In Composite Pattern , each Composite, i.e. individual objects and compositions of objects implement the common interface Component. For instance suggested in [Dp, Gof], here all the graphic objects implement the interface Graphic, where in Picture it acts as a container that stores a collection of Graphic and implement the methods (e.g. add, remove) to interact with it,  as in the composite interface, allowing objects to be compsoite together.

Builder Pattern

Builder Pattern is popular in the industry. One real life example of the pattern can be seen in the BDD framework, jbehave.

To configure how “stories” are run, there is an abstract class Configuration which provide methods to build the required configuration.

Reference documentation
http://jbehave.org/reference/stable/javadoc/core/org/jbehave/core/configuration/Configuration.html
http://jbehave.org/reference/stable/configuration.html

In fact, it also applied “Fluent interface” [Fowler], for increased readability
in each config method the builder instance is returned for further configuration. This make below code possible

</pre>
return new MostUsefulConfiguration()
 .useStoryControls(new StoryControls().doDryRun(false).doSkipScenariosAfterFailure(false))
 .useStoryLoader(new LoadFromClasspath(embeddableClass))
 .useStoryParser(new RegexStoryParser(examplesTableFactory))
 .useStoryPathResolver(new UnderscoredCamelCaseResolver())
 .useStoryReporterBuilder(
 new StoryReporterBuilder()
 .withCodeLocation(CodeLocations.codeLocationFromClass(embeddableClass))
 .withDefaultFormats().withPathResolver(new ResolveToPackagedName())
 .withViewResources(viewResources).withFormats(CONSOLE, TXT, HTML, XML)
 .withFailureTrace(true).withFailureTraceCompression(true).withCrossReference(xref))
 .useParameterConverters(parameterConverters)
 // use '%' instead of '$' to identify parameters
 .useStepPatternParser(new RegexPrefixCapturingPatternParser("%"))
 .useStepMonitor(xref.getStepMonitor());
<pre>

This make configuration easier and increased code readability

To use the Builder Pattern to build a Composite

There is a comprehensive example and guide in the book <<Refactor to Patterns>>[RP, Joshua Kerievsky]

As suggested by the author, building a Composite is repetitive, complicated, or error-prone. Builder can ease the creation of the composition.

The advantage is encapsulating the details of the building of composite. This also decouples the interface of the composite with the composition logic.

Using the example of composite [DP, Gof], here we apply the builder pattern to illustrate, .

It is desired to create graphic object which is composition of simpler graphic objects.
Note Line, Rectangle and Text are “primitive graphics” in this example, where they have no child graphics and none of these subclasses implements child-related operations. The type Picture is composite objects of the type Graphics and encapsulate a collection of graphics.

To have the object as suggested in [DP, Gof]

Without using Builder, following code has to be written


</pre>
Graphic rect = new Rect()
 Graphic line = new Line()
 line.setwidth(5px)
 Graphic text = new Text()
 text.setText(“abc”)

picB = new Graphic()
 picB.Add(rect)
 picB.Add(line)
 picB.Add(aText)

picA = new Shape()
 picA.Add(rect)
 picA.Add(line)
 picA.Add(picB)
<pre>

With Builder Pattern
Now introduce the builder pattern.
we create interface PictureBuiler as the builder.

interface PictureBuilder () {
addChildTo(Graphic parent)
addSibling(Graphic sibling)
}
methods like addChild or addSibling can be introduce into the Builder, which will wrap the method of adding / removing composite, in this example, Add, Remove and GetChild in Graphic.

The products of builder will need to implement the common interface and allow composition.
In the Concrete Builder interface, the interface for retrieving the product should be the Component interface.

We can create PictureConcreteBuilder, the concreteBuilder that do the actual work in building the Picture, including tranversing and linking up the tree structure.

Note how this satisfies the motivation of builder being “abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects.”

ConcreteBuilder
Below is a simplified possible implementation for ConcreteBuilder, the  PictureBuilderImpl. This class assemble the structure of the composite.

class PictureBuilderImpl() implements PictureBuilder {

Picture currentPicture;
Picture parentPicture;

Picture addChild(){
currentPicture.add(graphicToAdd);
currentPicture = graphicToAdd;
}

Picture addSibling(Graphic graphicToAdd){
parentPicture.add(graphicToAdd);
currentPicture = graphicToAdd;
}

Picture build(){
//return the top node
}

Picture getParent(){
}
}

Director
The Director to construct the object should handle the composite requirement logic.
Below code is now possible, as a typical sequence of method invocations during the building of a Composite instance

PictureBuiler picBuilder= new PictureConcreteBuiler();
picBuilder.addChild(TextType)
picBuilder.addSibling(LineType)
builder.addSibling(PictureType)
builder.addChild(LineType)
builder.addSibling(textType)
builder.addSibling(RectangleType)

Where the type of Graphic to be added can be determined using enum or Reflection to ensure type safety. This ensure the open-closed principle that even new shapes are aded no change is required in the builder.

In the builder internals, we add the reference of current Node / parent Node to establish tree structure and transverse it, keep tracking where to add the Graphic.

Alternative
Note it is also possible to use startPicture() and endPicture(), which start /end composite in the director.

PictureBuiler picBuilder= new PictureConcreteBuiler();
picBuilder.startComposite()
picBuilder.add(TextType)
picBuilder.add(LineType)
picBuilder.startComposite()
picBuilder.add(PictureType)
picBuilder.add(LineType)
picBuilder.add(textType)
picBuilder.endComposite()
picBuilder.endComposite()

Question 2

Discuss on Bridge & State
Bridge Pattern

in bridge pattern, the intent is to decouple an abstraction from its implementation so that the two can vary independently.

Consider below Example problem.

In application with UI, it is required to model the information being rendered to UI.
It is useful to put what to render in the abstraction, while how to retrieve the information in the implementation. Example like a Blog Site, the UI component evolved quickly while the content is independent. There are also different kind of BlogPosts including some with picture only, while another with Text only.

The Blog post rendering in UI can be SimpleBlogPost, or FeaturedBlogPost, which will have different layout and method of rendering.

When we use simple fulfill for the interface BlogPost, the implementation will be coupled with the abstraction. We wont be able to refine the contract / methods available.

To solve the problem, we can apply the bridge pattern by creating the BlogPost abstraction and SimpleBlogPost & FeaturedBlogPost as Refined Abstraction.

The two kinds of implementation TextBlogPost and PictureBlogPost that can make use of the same abstraction (BlogPostImpl)  which is a ConcreteImplementor  to render the blog post.

With bridge, now it is easier to modify / extend / refined the abstraction. For example, one can add PrivateBlogPost which implement another methods, for instance renderWithReaderList()

e.g.
Abstraction

public abstract class BlogPost(){

title
author
BlogPostImpl impl

private void renderContent() {

}

}

Implementor

public interface BlogPostImpl(){
renderContent()
}

Refined Abstraction:

SimpleBlogPost
public class SimpleBlogPost extends BlogPost (){

renderAsExcerpt() {
print title
print convertDateInFormat(date, locale.us)
}

convertDateInFormat(){
//concrete impl
}

renderAsFullDetails {
print title
print date
impl.renderContent();
}
}

FeaturedBlogPost
public class FeaturedBlogPost extends BlogPost(){

renderAsFeatured() {
//render special layout
impl.renderContent();
//render special layout
}
}

Concrete Implementor

public class PictureBlogPost implements BlogPostImpl
renderContent(){
//retrieve image from filesystem and render
}

public class TextBlogPost implements BlogPostImpl (){
renderContent(){
//retrieve text from Database and render

}

Here the refined abstraction hide the method render() of the abstract superclass, instead require subclasses to fulfil the specialized render methods (e.g. renderAsFeatured() in FeaturedBlogPost). (typo in diagram – blogpost shd have render() only)


State Pattern

For State pattern, it helps represent the state of an object. The advantage is to allow to object to changes its type & behaviour dynamically with its internal state, also separate the details of how a state is being handled and conditional logic to increase cohesion. (decrease cyclomatic complexity)

There are Context, State and ConcreteState as participants in this pattern.

Consider the blogpost scenario above, this state pattern can be useful in solving another related problem. It is desired to show different layout customization when user render the blog with full screen mode. With navie if-else handling with variable in context as state, there will be many duplication code in hanlding the state change, and they are coupled with the context (UI). The scope of variable is also not protected.

With State Pattern
We can have a ScreenState Object as the state. Then we can have concreteState being Full FullScreenStateand NonFullScreenState.

The context will detect the state and switch the state object dynamically. there are listener to the external screen setting change and invoke the request method in the context. Then in the request method of Context, method handle() of the interface ScreenState will be invoked.

Then in the concreteState objects, i.e.FullScreenState or NonFullScreenState, custom logic can be implemented to handle the rendering of the UI. e.g. disable sidebar in full screen mode.

Note the difference between the two,

State pattern focus on changing the behaviour dynamically, where here is the state of the screen setting. It is therefore named as behaviour pattern, which are concerned with algorithms and assignment of responsibilities between object and describe also the communication between them.   [DP, Gof]. Here the state pattern described how different handle method are being invoked in the state for invoking the request in the context, namely when fullscreen is toggled different behaviour can be handled dynamically.

Meanwhile,  bridge focus on establishing the type and structure of the behaviour. Structural patterns are concerned with how classes and objects are composed to form larger structures.  [Dp, Gof]. the bridge pattern described how to compose object to create new functionality. As in the example, new contract of features are created in the refined abstraction, like FeaturedBlogPost or SimpleBlogPost. This is a structural change that the implementation and abstraction can vary independently with bridge.

Question 3
static factory method

The difficulty is that the three constructors would then have the same signature and so could not co-exist.

we can solve the problem by modifying the Temperature class by adding the following three static factory methods and providing implementations for each of them:

private Temperature(double kelvin)
{
this.kelvin = kelvin;
}

public static Temperature fromCelsius(double degreesCelsius) {

return new Temperature(convertCtoK(degreesCelsius));

}
public static Temperature fromFahrenheit(double degreesFahrenheit) {

return new Temperature(convertFtoK(degreesFahrenheit));

}

public static Temperature fromKelvin(double kelvin) {

return new Temperature(kelvin);

}

Also modify the constructor such that it cannot be invoked directly by clients. Thus clients will be forced to use the factory methods to create new Temperature objects. Note it is private, using the notion of Java.

Advertisements

One thought on “Aside: Design Pattern: Composite, Builder, Bridge, State and static Factory

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s