Search your topic in Java2share
Home > FAQs
eXTReMe Tracker


Design Patterns FAQs


Untitled Document

Q9. When would I use the delegation pattern instead of inheritence to extend a class's behavior?

Both delegation and inheritance are important concepts in object-oriented software design, but not everyone would label them as patterns. In particular, the seminal book on design patterns by the “Gang of Four” contains a discussion of inheritance and delegation, but the authors do not treat these topics as specific patterns. It is reasonable to think of them as design concepts which are more general than specific design patterns.

Inheritance is a relationship between two classes where one class, called a subclass in this context, inherits the attributes and operations of another class, called its superclass. Inheritance can be a powerful design/reuse technique, especially when it is used in the context of the Liskov Substitution Principle. (The article by Robert Martin at http://www.objectmentor.com/publications/lsp.pdf provides an excellent explanation of the ideas behind Barbara Liskov’s original paper on using inheritance correctly.)

The primary advantages of inheritance are

1. it is directly supported by object-oriented languages, and
2. it provides the context for polymorphism in strongly-typed object-oriented
languages such as C++ and Java. But since the inheritance relationship is defined at compile-time, a class can’t change its superclass dynamically during program execution. Moreover, modifications to a superclass automatically propagate to the subclass, providing a two-edged sword for software maintenance and reuse. In summary, inheritance creates a strong, static coupling between a superclass and its subclasses.
Delegation can be viewed as a relationship between objects where one object forwards
certain method calls to another object, called its delegate. Delegation can also a powerful
design/reuse technique. The primary advantage of delegation is run-time flexibility – the
delegate can easily be changed at run-time. But unlike inheritance, delegation is not directly
supported by most popular object-oriented languages, and it doesn’t facilitate dynamic
polymorphism.
As a simple example, consider the relationship between a Rectangle class and a Window
class. With inheritance, a Window class would inherit its rectangular properties from class
Rectangle. With delegation, a Window object would maintain a reference or pointer to a
Rectangle object, and calls to rectangle-like methods of the Window object would be
delegated to corresponding methods of the Rectangle object.
Now let’s consider a slightly more complex example. Suppose employees can classified
based on how they are paid; e.g., hourly or salaried. Using inheritance, we might design
three classes: an Employee class which encapsulates the functionality common to all
employees, and two subclasses HourlyEmployee and SalariedEmployee which encapsulates
pay-specific details. While this design might be suitable for some applications, we would
encounter problems in a scenario where a person changes, say from hourly to salaried. The
class of an object and the inheritance relationship are both static, and objects can’t change
their class easily (but see the State pattern for tips on how to fake it).
A more flexible design would involve delegation – an Employee object could delegate payrelated
method calls to an object whose responsibilities focused solely on how the employee
is paid. In fact, we might still use inheritance here in a slightly different manner by creating
an abstract class (or interface) called PayClassification with two subclasses
HourlyPayClassification and SalariedPayClassification which implement classification-specific
computations. Using delegation as shown, it would be much easier to change the pay
classification of an existing Employee object.
This second example illustrates an important point: In implementing delegation, we often
want the capability to replace the delegate with another object, possibly of a different class.
Therefore delegation will often use inheritance and polymorphism, with classes of potential
delegates being subclasses of an abstract class which encapsulates general delegate
responsibilities.
One final point. Sometimes, the choice between delegation and inheritance is driven by
external factors such as programming language support for multiple inheritance or design
constraints requiring polymorphism. Consider threads in Java. You can associate a class
with a thread in one of two ways: either by extending (inheriting) directly from class
Thread, or by implementing the Runnable interface and then delegating to a Thread object.
Often the approach taken is based on the restriction in Java that a class can only extend
one class (i.e., Java does not support multiple inheritance). If the class you want to
associate with a thread already extends some other class in the design, then you would
have to use delegation; otherwise, extending class Thread would usually be the simpler
approach.

Q10. Which patterns were used by Sun in designing the Enterprise JavaBeans model?

Many design patterns were used in EJB, and some of them are clearly identifiable by their naming convention. Here are several:

1. Factory Method: Define a interface for creating classes, let a subclass (or a helper
class) decide which class to instantiate.This is used in EJB creation model. EJBHome defines an interface for creating the EJBObject implementations. They are actually created by a generated container class. See InitialContextFactory interface that returns an InitialContext based on a properties hashtable.

2. Singleton: Ensure a class has only one instance, and provide a global point of
access to it. There are many such classes.
One example is javax.naming.NamingManager

3. Abstract Factory: Provide an interface for creating families of relegated or
dependent objects without specifying their concrete classes.
We have interfaces called InitialContext, InitialContextFactory. InitialContextFactory
has methods to get InitialContext.

4. Builder: Separate the construction of a complex factory from its representation so
that the same construction process can create different representations.
InitialContextFactoryBuilder can create a InitialContextFactory.

5. Adapter: Convert the interface of a class into another interface clients expect.
In the EJB implementation model, we implement an EJB in a class that extends
SessionBean or a EntityBean. We don't directly implement the EJBObject/home
interfaces. EJB container generates a class that adapts the EJBObject interface by
forwarding the calls to the enterprise bean class and provides declarative
transaction, persistence support.

6. Proxy: Provide a surrogate for other object to control access to it.
We have remote RMI-CORBA proxies for the EJB's.

7. Memento: Without violating encapsulation, capture and externalize an object's
internal state so that the object can be restored to this state later.
Certainly this pattern is used in activating/passivating the enterprise beans by the
container/server.

Q11. What is an analysis pattern?

An analysis pattern is a software pattern not related to a language or implementation
problem, but to a business domain, such as accounting or health care. For example, in health care, the patient visit activity would be subject to a number of patterns.
There is a good overview from an OOPSLA '96 presentation at
http://www.jeffsutherland.org/oopsla96/fowler.html

A good text would be: Martin Fowler's Martin Analysis Patterns : Reusable Object Models,
ISBN: 0201895420, published by Addison-Wesley. In summary, analysis patterns are useful for discovering and capturing business processes.

Q12. What are the differences between analysis patterns and design patterns?

Analysis pattern are for domain architecture, and design pattern are for implementation mechanism for some aspect of the domain architecture. In brief, analysis pattern are more high level and more (end-user) functional oriented.