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

Explaination Merged

Uploaded by

aadit shah
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)
2 views

Explaination Merged

Uploaded by

aadit shah
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

The Composite pattern

1. Introduction –

I was listening to Car Talk, a popular weekly broadcast during which callers ask questions about their
vehicles. Before every program break, the show's hosts ask callers to dial 1-800-CAR-TALK, which
corresponds to 1-800-227-8255. Of course, the former proves much easier to remember than the latter, in
part because the words "CAR TALK" are a composite: two words that represent seven digits.

Humans generally find it easier to deal with composites, rather than their individual components.
Likewise, when you develop object-oriented software, it's often convenient to manipulate composites just
like you manipulate individual components. That premise represents the fundamental principle of the
Composite design pattern.

2. The Pattern
Composite objects: objects that contain other objects; for example, a drawing may be composed of
graphic primitives, such as lines, circles, rectangles, text, and so on.

Developers need the Composite pattern because we often must manipulate composites exactly the same
way we manipulate primitive objects. For example, graphic primitives such as lines or text must be
drawn, moved, and resized. But we also want to perform the same operation on composites, such as
drawings, that are composed of those primitives. Ideally, we'd like to perform operations on both
primitive objects and composites in exactly the same manner, without distinguishing between the two. If
we must distinguish between primitive objects and composites to perform the same operations on those
two types of objects, our code would become more complex and more difficult to implement, maintain,
and extend.

Implementing the Composite pattern is easy. Composite classes extend a base class that represents
primitive objects.

Figure-1

Avinash Gautam Page 1


Component represents a base class (or possibly an interface) for primitive objects, and Composite
represents a composite class. For example, the Component class might represent a base class for graphic
primitives, whereas the Composite class might represent a Drawing class. Leaf class represents a
concrete primitive object; for example, a Line class or a Text class. The Operation1() and
Operation2() methods represent domain-specific methods implemented by both the Component
and Composite classes.

The Composite class maintains a collection of components. Typically, Composite


methods are implemented by iterating over that collection and invoking the appropriate method for each
Component in the collection. For example, a Drawing class might implement its draw() method
like this:

// This method is a Composite method


public void draw() {
// Iterate over the components
for(int i=0; i < getComponentCount(); ++i) {
// Obtain a reference to the component and invoke its draw method
Component component = getComponent(i);
component.draw();
}
}

For every method implemented in the Component class, the Composite class implements a method
with the same signature that iterates over the composite's components, as illustrated by the draw()
method listed above.

The Composite class extends the Component class, so you can pass a composite to a method that
expects a component; for example, consider the following method:

// this method is implemented in a class that's unrelated to the


// Component and Composite classes
public void repaint(Component component) {
// the component can be a composite, but since it extends
// the Component class, this method need not
// distinguish between components and composites
component.draw();
}

The preceding method is passed a component either a simple component or a composite then it invokes
that component's draw() method. Because the Composite class extends Component, the
repaint()method need not distinguish between components and composites it simply invokes the
draw() method for the component (or composite).

Figure 1's Composite pattern class diagram illustrate one problem with the pattern: you must distinguish
between components and composites when you reference a Component, and you must invoke a
composite specific method, such as addComponent(). You typically fulfill that requirement by
adding a method, such as isComposite(), to the Component class. That method returns false for
components and is overridden in the Composite class to return true. Additionally, you must also cast
the Component reference to a Composite instance, like this:

Avinash Gautam Page 2


...
if(component.isComposite()) {
Composite composite = (Composite)component;
composite.addComponent(someComponentThatCouldBeAComposite);
}
...

Notice that the addComponent() method is passed a Component reference, which can be either a
primitive component or a composite.

3. Alternative Composite pattern implementation

Figure-2

If you implement Figure 2's Composite pattern, you don't ever have to distinguish between components
and composites, and you don't have to cast a Component reference to a Composite instance. So the code
fragment listed above reduces to a single line:
...
component.addComponent(someComponentThatCouldBeAComposite);
...

But, if the Component reference in the preceding code fragment does not refer to a Composite, what
should the addComponent() do? That's a major point of contention with Figure 2's Composite pattern
implementation. Because primitive components do not contain other components, adding a component to
another component makes no sense, so the Component.addComponent() method can either fail
silently or throw an exception. Typically, adding a component to another primitive component is
considered an error, so throwing an exception is perhaps the best course of action.

Q. Which Composite pattern implementation would you prefer and why?

Avinash Gautam Page 3


Class Explosion
ITERATOR PATTERN
The iterator pattern is a behavioural object design pattern. The iterator pattern allows for the
traversal through the elements in a grouping of objects via a standardized interface. An
Iterator interface defines the actions that can be performed. These actions include being able
to traverse the objects and also obtain the objects.
JavaSW features the widely used java.util.Iterator interface which is used to iterate through
things such as Java collections. We can write our own iterat or by implementing
java.util.Iterator. This interface features the hasNext(), next(), and remove() methods. When
writing an iterator for a class, it is very common for the iterator class to be an inner class of
the class that we'd like to iterate through.
Let's look at an example of this. We have an Item class, which represents an item on a menu.
An item has a name and a price.
Item.java

package com.cakes;

public class Item {

String name;
float price;

public Item(String name, float price) {


this.name = name;
this.price = price;
}

public String toString() {


return name + ": $" + price;
}
}

Here is the Menu class. It has a list of menu items of type Item. Items can be added via the
addItem() method. The iterator() method returns an iterator of menu items. The MenuIterator
class is an inner class of Menu that implements the Iterator interface for Item objects. It
contains basic implementations of the hasNext(), next(), and remove() methods.
Menu.java

package com.cakes;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Menu {

List<Item> menuItems;

public Menu() {
menuItems = new ArrayList<Item>();
}

public void addItem(Item item) {


menuItems.add(item);
}
public Iterator<Item> iterator() {
return new MenuIterator();
}

class MenuIterator implements Iterator<Item> {


int currentIndex = 0;

@Override
public boolean hasNext() {
if (currentIndex >= menuItems.size()) {
return false;
} else {
return true;
}
}

@Override
public Item next() {
return menuItems.get(currentIndex++);
}

@Override
public void remove() {
menuItems.remove(--currentIndex);
}

The Demo class demonstrates the iterator pattern. It creates three items and adds them to the
menu object. Next, it gets an Item iterator from the menu object and iterates over the items in
the menu. After this, it calls remove() to remove the last item obtained by the iterator.
Following this, it gets a new iterator object from the menu and once again iterates over the
menu items.
Demo.java

package com.cakes;

import java.util.Iterator;

public class Demo {

public static void main(String[] args) {

Item i1 = new Item("spaghetti", 7.50f);


Item i2 = new Item("hamburger", 6.00f);
Item i3 = new Item("chicken sandwich", 6.50f);

Menu menu = new Menu();


menu.addItem(i1);
menu.addItem(i2);
menu.addItem(i3);

System.out.println("Displaying Menu:");
Iterator<Item> iterator = menu.iterator();
while (iterator.hasNext()) {
Item item = iterator.next();
System.out.println(item);
}

System.out.println("\nRemoving last item returned");


iterator.remove();

System.out.println("\nDisplaying Menu:");
iterator = menu.iterator();
while (iterator.hasNext()) {
Item item = iterator.next();
System.out.println(item);
}

The console output is shown here.


Console Output

Displaying Menu:
spaghetti: $7.5
hamburger: $6.0
chicken sandwich: $6.5

Removing last item returned

Displaying Menu:
spaghetti: $7.5
hamburger: $6.0

Note that since the menu utilizes a Java collection, we could have used an iterator obtained
for the menu list rather than write our own iterator as an inner class.
CASE STUDY – INTERNET BASED WEATHER MONITORING STATION

The weather station is based on WeatherData object, which tracks current weather conditions
(temperature, humidity, and barometric pressure). We have to create an application that initially
provides three display elements:

 Current conditions
 Weather statistics
 Simple forecast

All these display elements are updated in real-time as the WeatherData object acquires the most
recent measurements.

This is an expandable weather station. We need to release an API so that other developers can write
their own weather displays and plug them right in.

APPLICATION OVERVIEW

The three players in the system are the weather station (the physical device that acquire actual
weather data), the WeatherData object (that tracks the data coming from the Weather Station and
updates the displays), and the display that shows the users the current weather conditions.

Figure-1: Weather Station

OUR JOB

Create an application that uses the WeatherData object to update three displays for current
conditions, weather stats, and forecast.
DISPLAY ELEMENTS

Figure-2: Display Elements

FIRST IMPLEMENTATION

public class WeatherData {

//instance variables
public void measurementChanged(){

//grab the most recent measurements by calling


//the WeatherData getter methods (already implemented)
float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();

//update the display by calling each display element to update


//its display, passing it the most recent measurements

currentConditionsDisplay.update(temp, humidity, pressure);

statisticsDisplay.update(temp, humidity, pressure);

forecastDisplay.update(temp, humidity, pressure);

}
} By coding to concrete implementations we have
no way to add or remove other display elements
without making changes to the program

Atleast we seem to be using a common interface to talk


to the display elements... they all have an update()
method takes the temp, humidity, and pressure data
Singleton pattern
Singleton pattern used when we want to allow only a single instance o f a class can be created insid e our
application. Using this pattern ensures that a class only have a single instance by protecting the class creation
process, by setting the class constructor into private access modifier.

To get the class instance, the singleton class can provide a method for example a getInstance() method, this will
be the only method that can be accessed to get the instance.

public class Service {

private static Service instance = null;

private Service() { }

public static synchronized Service getInstance() {


if(null == instance)
instance = new Service();

return instance;
}

protected Object clone() throws CloneNotSupportedException {


throw new CloneNotSupportedException("Clone is not
allowed.");
}
}

There are some rules that need to be followed when we want to implement a singleton.

1. A singleton has a static variable to keep it sole instance.


2. You need to set the class constructor into private access modifier. By this you will not allow any other class to
create an instance of this singleton because they have no access to the constructor.
3. Because no other class can instantiate this singleton, the singleton class should provide a service to its users by
providing a method that returns its singleton instance, for example getInstance().
4. When we use our singleton in a multi threaded application we need to make sure that instance creation process
doesn’t result in more than one instance, so we add a synchronized keywords to protect more than one thread
access this method at the same time.
5. It is also advisable to overri de the clone() method of the java.lang.Object class and throw
CloneNotSupportedException so that another instance cannot be created by cloning the singleton object.

You might also like