Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Design Patterns...

Reply
Thread Tools

Design Patterns...

 
 
secret
Guest
Posts: n/a
 
      09-24-2003
I've been reading the GoF book and it clicks (at last) as I'm reading it.
However, I think I (and maybe many others) would benefit greatly from
hearing about some real world uses of the patterns. What problems did they
actually help solve. Understanding the multitude of GUI examples in the
book does not help me to see applications in other areas and I fear that I
wouldn't recognize a relevant occasion to use some of them if I came across
it.

Here are some of the patterns to jog your memory...

Creational Patterns...
Abstract Factory,
Builder,
Factory Method,
Prototype,
Singleton

Structural Patterns
Adapter,
Bridge
Composite
Decorator
Facade
Flyweight
Proxy

Behavioural Patterns
Chain of Responsibility
Command
Interpreter
Mediator
Memento
Observer
State
Strategy
Template Method
Visitor
State Machine

Some of them are more self-explanatory than others, but real world examples
would be appreciated in any of them...

alan


 
Reply With Quote
 
 
 
 
John C. Bollinger
Guest
Posts: n/a
 
      09-24-2003
secret wrote:

> I've been reading the GoF book and it clicks (at last) as I'm reading it.
> However, I think I (and maybe many others) would benefit greatly from
> hearing about some real world uses of the patterns. What problems did they
> actually help solve. Understanding the multitude of GUI examples in the
> book does not help me to see applications in other areas and I fear that I
> wouldn't recognize a relevant occasion to use some of them if I came across
> it.
>
> Here are some of the patterns to jog your memory...
>
> Creational Patterns...
> Abstract Factory,
> Builder,
> Factory Method,
> Prototype,


Prototype (with Factory Method):

In a DNS client application, there is a class hierarchy for the various
types of DNS Resource Records. When constructing an object representing
a DNS response, it is necessary to obtain Resource Record objects of the
appropriate classes, based on the DNS resource record type and class codes.

The chosen solution was to give the ResourceRecord base class a
newInstance() method that creates and returns (as it says) a new
instance of ResourceRecord based on the parameters specific to a
particular raw record. Subclasses override this method appropriately,
providing instances of their own class. To construct the resource
record object the client looks up the class / type combination in a Map,
obtaining from it the appropriate prototype object, and then invokes the
newInstance method of the prototype. (And this is all performed inside
a Factory object, an implementation of one of the patterns you didn't
mention.)

Advantages:

(1) User can easily configure classes for new resource record types, or
alternative classes for supported resource record types.

(2) The client code is decoupled from specific resource record
implementations.

(3) No use of reflection.

> Singleton


Singleton:

[Comment: this one is overused in my experience, perhaps because it is
fairly easy to understand. This pattern should be applied only when it
is _necessary_ that there be only one instance.]

As a somewhat abstract description of another real example, take a case
where a collection of objects in potentially many threads need to draw
unique numbers from a continuous sequence (serial numbers, for
instance). Suppose also that these disparate objects have no direct
knowledge of each other. In order that all possible objects that use
the same sequence, the sequence is encapsulated in a Singleton object.
When an object needs a number from the sequence, it obtains the (one)
instance of the Singleton and invokes the appropriate method on it.

> Structural Patterns
> Adapter,


Adapter:

A user must write tests for two different implementations of the same
basic functionality. Instead of two completely different test suites,
the user writes one suite and for each implementation one adapter class
so that the test suite can work with either one.

> Bridge
> Composite
> Decorator


Decorator:

[From JUnit] a JUnit TestSuite instance defines one or more tests to be
run. For each one there is a setup step, a test step, and tear down
step; these are run sequentially. TestSuite implements an interface
Test, via which the group of tests is executed. If it is desired to
perform a setup and/or teardown procedure for the whole suite, then the
TestSuite can be decorated by a TestSetup that defines them; TestSetup
also implements Test and wraps a TestSuite.

> Facade
> Flyweight
> Proxy
>
> Behavioural Patterns
> Chain of Responsibility
> Command
> Interpreter
> Mediator
> Memento
> Observer
> State
> Strategy


Strategy:

[From Java Collections] The Comparator interface and all its
implementations. The Collections and Arrays classes provide generic
methods by which to sort objects; the specific sort order is directed by
a Comparator instance. Different Comparators give you potentially
different sort orders.

> Template Method


Template Method:

[Also from Java Collections] The AbstractCollection class defines an
entire Collection implementation in terms of abstract iterator() and
size() methods, and a stub add(Object) method. These three (especially
the first two) are template methods -- a concrete subclass can override
just those and thereby fully implement Collection in any manner desired.

Other AbstractXXX classes among the Collection classes work similarly.

> Visitor
> State Machine



John Bollinger
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
secret
Guest
Posts: n/a
 
      09-24-2003
Thanks John, that's fantastic. Very helpful.

alan

"John C. Bollinger" <(E-Mail Removed)> wrote in message
news:bkt63f$kgt$(E-Mail Removed)...
> secret wrote:
>
> > I've been reading the GoF book and it clicks (at last) as I'm reading

it.
> > However, I think I (and maybe many others) would benefit greatly from
> > hearing about some real world uses of the patterns. What problems did

they
> > actually help solve. Understanding the multitude of GUI examples in the
> > book does not help me to see applications in other areas and I fear that

I
> > wouldn't recognize a relevant occasion to use some of them if I came

across
> > it.
> >
> > Here are some of the patterns to jog your memory...
> >
> > Creational Patterns...
> > Abstract Factory,
> > Builder,
> > Factory Method,
> > Prototype,

>
> Prototype (with Factory Method):
>
> In a DNS client application, there is a class hierarchy for the various
> types of DNS Resource Records. When constructing an object representing
> a DNS response, it is necessary to obtain Resource Record objects of the
> appropriate classes, based on the DNS resource record type and class

codes.
>
> The chosen solution was to give the ResourceRecord base class a
> newInstance() method that creates and returns (as it says) a new
> instance of ResourceRecord based on the parameters specific to a
> particular raw record. Subclasses override this method appropriately,
> providing instances of their own class. To construct the resource
> record object the client looks up the class / type combination in a Map,
> obtaining from it the appropriate prototype object, and then invokes the
> newInstance method of the prototype. (And this is all performed inside
> a Factory object, an implementation of one of the patterns you didn't
> mention.)
>
> Advantages:
>
> (1) User can easily configure classes for new resource record types, or
> alternative classes for supported resource record types.
>
> (2) The client code is decoupled from specific resource record
> implementations.
>
> (3) No use of reflection.
>
> > Singleton

>
> Singleton:
>
> [Comment: this one is overused in my experience, perhaps because it is
> fairly easy to understand. This pattern should be applied only when it
> is _necessary_ that there be only one instance.]
>
> As a somewhat abstract description of another real example, take a case
> where a collection of objects in potentially many threads need to draw
> unique numbers from a continuous sequence (serial numbers, for
> instance). Suppose also that these disparate objects have no direct
> knowledge of each other. In order that all possible objects that use
> the same sequence, the sequence is encapsulated in a Singleton object.
> When an object needs a number from the sequence, it obtains the (one)
> instance of the Singleton and invokes the appropriate method on it.
>
> > Structural Patterns
> > Adapter,

>
> Adapter:
>
> A user must write tests for two different implementations of the same
> basic functionality. Instead of two completely different test suites,
> the user writes one suite and for each implementation one adapter class
> so that the test suite can work with either one.
>
> > Bridge
> > Composite
> > Decorator

>
> Decorator:
>
> [From JUnit] a JUnit TestSuite instance defines one or more tests to be
> run. For each one there is a setup step, a test step, and tear down
> step; these are run sequentially. TestSuite implements an interface
> Test, via which the group of tests is executed. If it is desired to
> perform a setup and/or teardown procedure for the whole suite, then the
> TestSuite can be decorated by a TestSetup that defines them; TestSetup
> also implements Test and wraps a TestSuite.
>
> > Facade
> > Flyweight
> > Proxy
> >
> > Behavioural Patterns
> > Chain of Responsibility
> > Command
> > Interpreter
> > Mediator
> > Memento
> > Observer
> > State
> > Strategy

>
> Strategy:
>
> [From Java Collections] The Comparator interface and all its
> implementations. The Collections and Arrays classes provide generic
> methods by which to sort objects; the specific sort order is directed by
> a Comparator instance. Different Comparators give you potentially
> different sort orders.
>
> > Template Method

>
> Template Method:
>
> [Also from Java Collections] The AbstractCollection class defines an
> entire Collection implementation in terms of abstract iterator() and
> size() methods, and a stub add(Object) method. These three (especially
> the first two) are template methods -- a concrete subclass can override
> just those and thereby fully implement Collection in any manner desired.
>
> Other AbstractXXX classes among the Collection classes work similarly.
>
> > Visitor
> > State Machine

>
>
> John Bollinger
> (E-Mail Removed)
>



 
Reply With Quote
 
Harald Hein
Guest
Posts: n/a
 
      09-25-2003
"secret" wrote:

> I've been reading the GoF book and it clicks (at last) as I'm
> reading it. However, I think I (and maybe many others) would
> benefit greatly from hearing about some real world uses of the
> patterns. What problems did they actually help solve.
> Understanding the multitude of GUI examples in the book does not
> help me to see applications in other areas and I fear that I
> wouldn't recognize a relevant occasion to use some of them if I
> came across it.


You don't need a pattern if you don't recognize an opportunity to use a
pattern. No joke! A common beginner's error is to look out for
opportunities to apply patterns and then plaster a whole application
with all kinds of patterns. Which just adds overhead and complexity.

A pattern give you a certain flexibility in your application. If you
don't need that flexibility, you are just adding overhead.

First you need to have a problem at hand! If you see one in your code,
you try to define the problem (something a lot of posters who post here
with brain-dead "help!!! XYZ does not work!!!" posts fail to manage at
all). Defining the problem includes listing the requiements for a
solution. Then you search for a solution satisfying the requirements.
While you do this, you also think about the patterns you know. Maybe
one fixes the problem. But, every pattern comes with a price. So you
also evaluate if you are willing to pay the price. If you are, go for
it. If not, continue to search.

The key to master patterns is not to apply them whenever possible. The
key is to stay away from them when not needed.

> Some of them are more self-explanatory than others, but real world
> examples would be appreciated in any of them...


Every example in the GoF book is a real-world example. In fact, every
pattern description ends with a list of known usages. But ok, here are
some more:

> Abstract Factory,


This is almost a meta-meta pattern. Instead of just having a factory
which shields object creation from the user, one also allows to
select/replace the factory itself. So you actually end up with a two-
step procedure:

1) Select factory at some point in time - maybe even hiden from you
2) Creat specific object from the range of objects the factory
can create

Sometimes, step 1) is also done using a factory. So you end up with a
three step-procedure starting with a factory creating a factory ...

If you need this pattern, you usually need it badly. Otherwise, stay
away from it.

Last time I used this when I had to incooperate communication with two
legacy systems into a new application. Both systems did the same thing,
but with a completely different communication protocol. So the first
step was to provide adapters for both systems to map the
communication with both of them to a unified interfaces. The rest of
the system only knew how to work with the unified interfaces.

The second step was to provide two separate factories that could
generate the adapter objects. Both factories implemented the same
interface. The interface served as the abstract factory (I didn' use an
abstract base class, because there was no implementation to share).

At the start of the system a simple factory method was used to select
the factory class, based on user input, user rights, pre-configurations
and availability of the external systems.

> Builder,


I had to create an application that was supposed to create a lot of
reports. Due to the amount of data it was not possible to store all
data neded for the reports until the end of the application. So
unfortunately, the reports had to be generated while the application
ran. And it had to support a lot of different report formats.

So the application got a reporting interface which dispatched the
intermediate results delivered to the interface to concrete builder
implementations for the different reporting formats. The Builders
generated the reports on the fly as soon as they had enough data for
their specific report format.

> Factory Method,


Usually used in conjunction with someting else. E.g the usage of the
flyweight pattern described below was done using a factory method. The
creation of a particular factory class in the abstract factory example
was also done using a factory method.

> Prototype,


I sometimes see people using this pattern when they don't know it. E.g.
when people mimic copy constructors:

class MyClass {
/** Initialize new object from old object **/
public MyClass(MyClass other) {
this.someValue = other.someValue;
}
}

All it would take to make this an application of the prototype pattern
more obvious would be some renaming:

class MyClass {
/** Use a prototype to initialize new object **/
public MyClass(MyClass prototype) {
this.someValue = prototype.someValue;
}
}

This is nice, but not very poweful. So you e.g. end up with a factory
like this:

class MyFactory {
public setPrototype(MyClass prototype) {
this.prototype = prototype;
}
public creatMyClass() {
return new MyClass(this.prototype);
}
}

You coud do the same using cloning instead of this copy-constructor
fakeing.

I really don't remember when I used it this way last time. It just
happens. I do remember that I used something similar in a constructor,
where the default data for objects was read from a properties file.
Instead of reading the properties file every time when a new object of
that type was constructed I just read the data once and buffered it.
The buffer was a "half initialized" object. But that implementation
would more count as an application of the "first-time in" pattern:

class MyClass {
static MyClass default_ = null;
public MyClass() {
if(default_ == null) {
// first-time in, get default data
default_ = readDataFromPropertyFile();
}
this.someValue = default_.someValue;
this.anotherValue = default_.anotherValue;
}
}

> Singleton


Overused. As a beginner, stay away from it! If you ever implement it in
a thread-save way, DO NOT optimize it with he double-check lock
pattern. Double-check lock can't work reliable due to Java's memory
model,

> Adapter,


See my abstract factory example. In order to integrate the legacy
systems, both interfaces to the systems need to be unified. This was
done with a set of adapters.

> Flyweight


In a certain engineering program I needed thousands of objects to
represent the data (think of a simulation). Each object had a set of
attributes holding its configuration state and its specific data. Due
to the nature of the application usually almost all objects had the
same configuration state, which never changes during the application.

Instead of having the 25 or so different configuration state variables
in each object, each object only had one referenc to a configuration
state object from a pool of flyweights. The state objects were
immutable. When a new data object was created, the pool was queried for
a state object (using a factory method). If a matching one existed the
reference to the matching one was returned. If non existed, a new one
was created, added to the pool and returned.

> Visitor


In a planning application a lot of different calculations had to be
done on the data. And I knew from the beginning that once the
first calculations were implemented people would ask for more. So
instead of implementing the calculations with the data-holding objects,
they all got a visitor interface.

On top of that there was a simple "query engine". All this engine did
was to (a) find the right entry into the huge pile of data (based on
some start date, project name, etc.), (b) configured a visitor to do
the necessary navigation inside the data (which trails to follow, end
date, etc.), and (c) started the visitor on the first object. After
some time the visitor returned with the right result.

It was really fun to sit on top of this pile of data and just fire
visitor calculation requests into it.
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      09-25-2003
On Wed, 24 Sep 2003 19:26:26 GMT, "secret" <(E-Mail Removed)> wrote
or quoted :

>What problems did they
>actually help solve.


Have a look at pattern usage in the Java class libraries.

see http://mindprod.com/jgloss/border.html for simple use of a
factory.

See JTable for Model View Controller (well not quite).

See Iterator for Iterator.

see http://mindprod.com/jgloss/parser.html and follow to Qiotix to see
the visitor pattern.

--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Class design/design pattern resources TomTom MCSD 2 10-09-2004 07:38 AM
OO design in servlet design question dave Java 5 07-17-2004 12:58 PM
Xilinx Schematic design vs VHDL code design ZackS VHDL 5 07-09-2004 07:51 AM
Looking for help/resources on Writing a nice detailed design / tech design for vb.net code SpamProof Java 3 12-01-2003 06:06 AM



Advertisments