Skip to content

Patterns

Basically ask yourself – what problem does this design solve? Think of the problem first and then suggest the design. Easy to understand.The difference between patterns is generally in intent.

Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex)

Creation Patterns

Factory Method:centralize creation of an object of a specific type choosing one of several implementations

One method that delivers concrete implementations (producers) directly to clients.Can be a static method of a static class – then called static method = Simple Factory (Eg: DriverManager.getConn)

Another impt point is that the concrete class that supplies objects can be derivable – only then it qualifies to be the actual factory method – (if only static/static – it’s simple factory).IFactory factory = new ConcreteFactory();

While a “simple” factory loosely couples the construction of the product from the client, it does not decouple the factory. The factory pattern also decouples the factory.

Abstract Factory :centralize decision of what factory to instantiate

It’s called as a kit to produce a range of products. So first you have a concrete producer and then a type of product created respecting the core interface by that producer. All producers inherit the base abstract class and produce products which are again in inheritance.

The clients only know of the base producer and the base products. The choice of  concrete producer/products to produce are left on to the abstract class – generally abstract class keeps a handle to the actual producer in the form of a singleton method / or it can also be a factory method in it.

Difference between factory and abstract factory is this – that abstract factory has a set of factories which it can use to create a set of one type of objects. Actual manufacturer hidden from the Client – so that helps when you need to add more classes in heirarchy. Client code is not disturbed with concrete implementations.

Abstract factory can generally have one factory method to create the necessary concrete factory implementation.

Factory method pattern generally hands over the actual product instead of the the producer (AF) to the Client.

/* Classes
Products:
Fruit
FloridaOrange
NYOrange
FloridaApple
NYApple

Producer
FloridaFruitsProducer
NYFruitsProducer

createFruit();
printColor
*/

abstract class FruitManufacturers{

abstract createFruit();
abstract printColor();
// get concrete producer = simple factory static method here
P getProducer (){ return SomeConcreteProducer(); }
}

Factory Method: Client knows the manufacturer. Directly invokes method to get objects.

Factory Method generally involves getting any one Product in hierarchy given the Producer – known to client.
Inheritance used here:

interface FruitManufacturers {
 createFruit();
 printColor();
}

The intent of Factory Method is “Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”

The intent of Abstract Factory is “Provide an interface for creating families of related or dependent objects without specifying their concrete classes.”

Factory Method is in some sense a “degenerate” Abstract Factory with a family of one.

Summary: Factory Method – client knows creator, one product in hierarchy. AF – client does not know creator and multiple products existing.

————————————————————————————-

Builder: attributes known to create object complex and ordered, so each subclass in heirarchy overrides the sub set of operations required to build the object.  Builder is only needed when an object cannot be produced in one step.

It is almost similar to abstract factory – you do have base producer and inheritance of it – but product is one – (Not in a heirarchy) which has multiple op’s that are implemented differently by each of the concrete producers. And the Director or the Client has to manually invoke each sub-operation!. (This is completely unlike the factory)

Also another use case is when you start to see more than  4 or 5 parameters to construct an object. 

Revised Builder – is very neat as it ensures complete object construction and no setters – so clean.

/* Director using the builder */
public class StitchDirector()
{
  /* Builder interface implemented by ThreadNeedleworkBuilder and WoolenNeedleworkBuilder*/
  private NeedleworkBuilder builder;

  public void construct(){
	fetchCloth();
	fetchAtta();
	thread();
	needle();
	bind();
	stitch();
  }

  public Work getWorkBuild(){
	builder.getBuild();
   }

}

http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html

Prototype

This pattern is used to create objects which are copies of a given original object – and these can be deep copies – advantage of doing a copy is:
– save on expensive calls for creating a object using new
– need not subclass – but after copying the original make changes in the copied object.

You can use a prototypeFactory to keep registry of original objects from whom copy has to be made.
This factory can be created through DI etc.

Singleton



Proxy Pattern

So first you create the .class file with that name – and having all the methods.Gets all methods , fields etc and writes them to output stream -> Byte Array output stream. Proxy builds a Java class into a byte array and then loads it into the JVM with a private native defineClass0 method.

Proxy is an interface that has a method called newProxyInstance that takes the class, interface, and the wrapper invoker.

The class and interface are used to define a runtime class CL1

CL1 {
//InvocationHandler h;

//has all the methods of INTF1
}

CL1 – the runtime created class has a reference to the wrapper impl h.
It uses the calls of all the methods to be delegated to h.

Once CL1 is loaded in memory after being defined through reflection and a native call named defineClass0 then the constructor of the class is called with the parameter of h. and a new instance of CL1 is created.

This instance is returned back as the proxy instance. All calls now on this instance will call the invoke method of the wrapper class and will be upto the wrapper how it delegates back to the original subject.

Proxy pattern – do not use a wrapper class because of additional methods not implemented limitations.Need to take care of the

  • exceptions that can be thrown.
  • equals method

Structural patterns: proxy,adapter, composite and decorator.

In proxy – clients talk to subject not to the implementation (hide the impl) . In decorator clients talk to the implementation class that has added on features. Dynamic proxy uses only interfaces (JavaCompiler allows subclassing and also for improved performance).

CGLIB Proxy -vs – JDK Proxy….

Object Adapter: implements target interface and delegates calls to nested objects inside. (Delegation) /OR/ extends the target class and delegates to nested objects.

Class Adapter: Extends the existing class and implements target interface and call’s the super class methods

Strategy Pattern
1. Inheritance is for behavior and NOT for state.

2. Can use any of the 4 factory methods – ? creational patterns for choosing the right strategy class.

3. Vtable lookup – if more than 3 concrete strategies otherwise if/else statements used by compiler,

4. Strategy objects contain some state – if you increase number of objects – then it may cause some issue.

Adapter
class adapter – override
object adapter – does not allow to override methods

public constructr(final Enumeration en)
{

this(new Iterator() { //using the en over here to next() { en.nextElement();}
// question is: how are we using the final variables in the nested anonymous classes?
}

Iterator
always make sure you know the INTENT of the structure. If the INTENT is known the pattern will be known.
Otherwise sometimes its dificult to say looking at the structure what kind of pattern was used.

internal and external iterator.
some iterator have int – that tell which position to start with – no reset – but can move previous/next
insert/remove does not impact traversal


If client is not aware it’s proxy.
2 decorator : 1 adds state, and You can add or remove functionality but not throw exeotion: Collections.unmodifiableMap – / add remove throws Exception.

buffered input stream and gip are actually forms of proxy. because client would never point directly to gzipoutputstream.
structure is not sufficient to decide the design pattern we need to ask the intent. decorator augments the interface but proxy augments the call.

Composite pattern:
Problem: Need to treat the container and component in a similar manner – do not wish to differentiate between the two – remove the complexity of handling leaf and component differently.

There can be different layers of nesting of containers within containers – and in the end it has a leaf.

C1.add(c2);
C3.add(c1)l
c.add(c3);

Two flavors – in some cases only the container class has the additional methods , in other cases – all operations even if not required by leaf are pushed up to parent component so that both inherit it.

—————————————————————————————

Structural Patterns

—————————————————————————————

Flyweight:

Flyweight  object can be shared: Now either that whole object is sharable and u store it in a cache.

Or you can partition that object into shareable and non shareable part – where in the intrinsic state is the cached one, the extrinsic state is provided by the client.

Reduced memory footprint of the object created – is called flyweight.

 

Behavioral Patterns

Visitor

Visitor

Class hierarchy already existing – and you want to add algo’s doing some data manipulation in these classes – but do not want to add new methods to that family – then use visitor. Visitor – it’s a way of structuring double dispatch, Also multiple data calculations involved – not just usage of type for visit calls.

 

In some ways – other than double dispatch – it’s a nice way of removing switch and letting compiler figure which method to call based on the parameter type.

 

 

So class implements accept – which takes in the visitor – the visitor call’s its own API – visit that takes in the current object as parameter – so all data is forwarded to that algo. Based on the data type of the current object the call gets executed.

 

So I will have the following visit existing:

class VisitorTest implements Visitor{

Public void visit(Cat c) { change sound to purr}

Public void visit(Dog d) { bark}

Public void visit(Fish f) { float}

}

 

Interface Visitor{

Public void visit(Cat c);

Public void visit(Dog d);

Public void visit(Fish f);

}

 

 

Class Cat extends Animal{

Public void accept(Visitor v)

{

v.visit(this);

}

}

 

that C++ didn’t have any form of Run-Time Type Identification (RTTI). They used “double dispatch” to get the target objects to tell them what their type was. But problem above maybe that every time a new class is added to Animal the Visitor implementations + visitor interface – a new method needs to be added. To avoid that you can use generics :

Basically store all visitors for each data type into a map – and every time a new class added put it in the map only.

 

public interface Visitor<T> {

void visit(T type);

}

 

 

public class VisitorRegistry {

private Map<Class<?>, Visitor<?>> visitors = new HashMap<Class<?>, Visitor<?>>();

public <T> void register(Class<T> clazz, Visitor<T> visitor) {

visitors.put(clazz, visitor);

}

 

public <T> void visit(T thing) {

// needs error checks, and possibly “walk up” to check supertypes if direct type not found

// also — can provide default action to perform – maybe register using Void.class?

@SuppressWarnings(“unchecked”)

Visitor<T> visitor = (Visitor<T>) visitors.get(thing.getClass());

visitor.visit(thing);

}

}

 

Also – it can be used for recursive operations – along with composite

The Visitor pattern allows you to define new operations on the elements of an object structure without changing the element classes on which they operate. During usage, a Visitor visits each element in the structure via recursive descent (if the elements are contained in a Composite structure), or via iteration (over the elements of a Collection), or via a combination of both (if visited elements are both composed and collected).

 

 

 

Advertisements
No comments yet

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

%d bloggers like this: