Module 3 Updated
Module 3 Updated
Convert the
interface of a
class into another
Interface clients
expect.
Department
Departmentof
ofISE
ISE BMS Institute of
Tec
Pattern Name: Adapter
Intent:
⮚ Convert the interface of a class into another interface clients
expect. Adapter lets classes work together that could not
otherwise because of incompatible interfaces.
Collaborations:
⮚ Clients call operations on an Adapter instance. In turn, the
adapter calls Adaptee operations that carry out the request.
SpecficRe ueet()
{«zipzamcritatic•
n)
adapae— SpecificRequast()
Participants
• Target (Shape)
- defines the domain-specific interface that Client uses.
• Client (DrawingEditor)
- Collaborates with objects conforming to the Target interface.
• Adaptee (TextView)
- defines an existing interface that needs adapting.
• Adapter (TextShape)
- adapts the interface of Adaptee to the Target interface.
Collaborations
• Clients call operations on an Adapter instance. In
turn, the adapter calls Adaptee operations that
carry out the request.
Consequences
Class and object adapters have different trade-offs.
❖ A class adapter
• adapts Adaptee to Target by committing to a concrete Adaptee
class. As a consequence, a class adapter won't work when we
want to adapt a class and all its subclasses.
• lets Adapter override some of Adaptee's behavior, since Adapter
is a subclass of Adaptee.
• introduces only one object, and no additional pointer indirection
is needed to get to the adaptee.
❖ An object adapter
• lets a single Adapter work with many Adaptees—that
is, the Adaptee itself and all of its subclasses (if any). The
Adapter can also add functionality to all Adaptees at once.
• makes it harder to override Adaptee behavior. It will require
subclassing Adaptee and making Adapter refer to the subclass
rather than the Adaptee itself.
Issues to be consider when using the Adapter pattern:
▪ How much adapting does Adapter do?
▪ Pluggable adapters: describe classes with built-in interface
adaptation.
▪ Using two-way adapters to provide transparency.
Implementation:
Issues to keep in mind while implementing Adapter:
1. Implementing class adapters in C++. Adapter would inherit
publicly from Target and privately from Adaptee.
• Thus adapter would be subtype of target but not of Adaptee
2. Pluggable adapters.
find a "narrow" interface for Adaptee the smallest subset of
operations that lets us do the adaptation.
The narrow interface leads to three implementation approaches:
a. Using abstract operations.
b. Using delegate objects.
c. Parameterized adapters.
a. Using abstract
operations.
2. Improved
• You can extend the Abstraction and
extensibility.
Implementor hierarchies independently.
3. Hiding implementation details from clients.
• You can shield clients from implementation details,
like the sharing of implementor objects and the
accompanying reference count mechanism (if any).
Department of ISE
Related Patterns:
1. An Abstract Factory can create and configure a
particular Bridge.
2. The Adapter pattern is geared toward making
unrelated classes work together.
Department
Departmentof
ofISE
ISE BMS
BMSInstitute
Institute
of of
Technology
Technology
and
and
Mgmt
Mgmt
5. Should Component implement a list of Components?
• Usually we define the set of children as an instance variable
in the Component class where the child access and
management operations are declared.
• But putting the child pointer in the base class incurs a space
penalty for every leaf, even though a leaf never has children.
• This is worthwhile only if there are relatively few children in
the structure.
• That is have few children
6. Child ordering.
• Many designs specify an ordering on the children of Composite.
• Graphics example, ordering may reflect front-to-back ordering.
• If Composites represent parse trees, then compound
statements can be instances of a Composite whose children
must be ordered to reflect the program.
• When child ordering is an issue, one must design child access
and management interfaces carefully to manage the sequence
of children.
• The Iterator ( 257)pattern can guide you in this.
7. Caching to improve performance.
• To traverse or search compositions frequently, the Composite class
can cache traversal or search information about its children.
• The Composite can cache actual results or just information that lets
it short-circuit the traversal or search.
• Changes to a component will require invalidating the caches of its
parents.
• This works best when components know their parents.
BMS Institute of Technology and Mgmt
8. Who should delete components?
• In languages without garbage collection, it's usually best to
make a Composite responsible for deleting its children when
it's destroyed.
• An exception to this rule is when Leaf objects are immutable
and thus can be shared.
Department
Departmentof
ofISE
ISE BMS
BMSInstitute
Institute
of of
Technology
Technology
and
and
Mgmt
Mgmt
The ScrollDecorator and BorderDecorator classes
are subclasses of Decorator, an abstract class for
visual components that decorate other visual
components.
Department
Departmentof
ofISE
ISE BMS
BMSInstitute
Institute
of of
Technology
Technology
and
and
Mgmt
Mgmt
Participants
• Component (VisualComponent)
- defines the interface for objects that can have
responsibilities added to them dynamically.
• ConcreteComponent (TextView)
- defines an object to which additional responsibilities can
be attached.
• Decorator
- maintains a reference to a Component object and
defines an interface that conforms to Component's
interface.
• ConcreteDecorator (BorderDecorator, ScrollDecorator)
- adds responsibilities to the component.
1. Flyweight (Glyph)
▪ declares an interface through which flyweights can receive and act on
extrinsic state.
2. ConcreteFlyweight (Character)
▪ implements the Flyweight interface and adds storage for intrinsic state, if
any.
▪ A ConcreteFlyweight object must be sharable.
▪ Any state it stores must be intrinsic; it must be independent of the
ConcreteFlyweight object's context.
3. UnsharedConcreteFlyweight (Row ,Column)
▪ not all Flyweight subclasses need to be shared.
▪ The Flyweight interface enables sharing; it doesn't enforce it.
▪ It's common for UnsharedConcrete- Flyweight objects to have
ConcreteFlyweight objects as children at some level in the flyweight
object structure (as the Row and Column classes have).
Participants contd…
4. FlyweightFactory
▪ creates and manages flyweight objects.
▪ ensures that flyweights are shared properly. When a client requests
a flyweight,
▪ the FlyweightFactory object supplies an existing instance or creates
one, if none exists.
5. Client
▪ maintains a reference to flyweight(s).
▪ computes or stores the extrinsic state of flyweight(s).
Collaborations
⮚ State that a flyweight needs to function must be characterized
as either intrinsic or extrinsic.
⮚ Intrinsic state is stored in the ConcreteFlyweight object;
⮚ Extrinsic state is stored or computed by Client objects.
⮚ Clients pass this state to the flyweight when they invoke its
operations.
• Clients should not instantiate ConcreteFlyweights directly.
• Clients must obtain ConcreteFlyweight objects exclusively from
the FlyweightFactory object to ensure they are shared properly.
Consequences
⮚ Flyweights may introduce run-time costs associated with
transferring, finding, and/or computing extrinsic state, especially if
it was formerly stored as intrinsic state.
⮚ such costs are offset by space savings, which increase as more
flyweights are shared.
Storage savings are a function of several factors:
• The reduction in the total number of instances that comes from
sharing
• The amount of intrinsic state per object
• Whether extrinsic state is computed or stored.
The more flyweights are shared, the greater the storage savings. The
savings increase with the amount of shared state.
Implementation
Consider the following issues when implementing the Flyweight
pattern:
• To keep from allocating space for a font attribute in every glyph, we'll
store the attribute extrinsically in a GlyphContext object.
• GlyphContext acts as a repository of extrinsic state.
• Any operation that needs to know the glyph's font in a given context will
have a GlyphContext instance passed to it as a parameter. The
• operation can then query the GlyphContext for the font in that context.
• The context depends on the glyph's location in the glyph structure.
• Therefore Glyph's child iteration and manipulation operations must
update the GlyphContext whenever they're used.
• GlyphContext must be kept informed of the current position in the glyph
structure during traversal.
Consider the following excerpt from a glyph composition:
The BTree structure for font information might look like
Department
Departmentof
ofISE
ISE BMS Institute
of
Class Glyph Factory instantiates Character and
other kinds of glyphs.
Known Uses
1. Interviews 3.0:
• Its developers built a powerful document editor called Doc as a
proof of concept [CL92]. Doc uses glyph objects to represent
each character in the document.
• Only position is extrinsic, making Doc fast. Documents are
represented by a class Document, which also acts as the
FlyweightFactory.
2. ET++:
• uses flyweights to support look-and-feel independence.
• The look-and-feel standard affects the layout of user interface
elements.
• A widget delegates all its layout and drawing behavior to a
separate Layout object. Changing the Layout object changes the
look and feel, even at run-time.
Department of ISE BMS Institute of Technology and Mgmt
Related Patterns
• The Flyweight pattern is often combined with the Composite
( 163) pattern to implement a logically hierarchical structure
in terms of a directed-acyclic graph with shared leaf nodes.
• It's often best to implement State (305) and Strategy
(315) objects as flyweights
• The image proxy creates the real image only when the document
editor asks it to display itself by invoking its Draw operation.
• The proxy forwards subsequent requests directly to the image. It
must therefore keep a reference to the image after creating it.
• Let's assume that images are stored in separate files.
• we can use the file name as the reference to the real object.
• The proxy also stores its extent, that is, its width and height.
• The extent lets the proxy respond to requests for its size from
the formatter without actually instantiating the image.
Department
Departmentof
ofISE
ISE BMS
BMSInstitute
Institute
of of
Technology
Technology
and
and
Mgmt
Mgmt
• The document editor accesses embedded images through the
interface defined by the abstract Graphic class.
• ImageProxy is a class for images that are created on demand.
• ImageProxy maintains the file name as a reference to the
image on disk.
• The file name is passed as an argument to the ImageProxy
constructor.
• ImageProxy also stores the bounding box of the image and a
reference to the real Image instance.
• This reference won't be valid until the proxy instantiates the real
image.
• The Draw operation makes sure the image is instantiated before
forwarding it the request.
• GetExtent forwards the request to the image only if it's
instantiated; otherwise ImageProxy returns the extent it stores.
The following method assumes the proxy has a real Subject method that returns
its real subject.
Known Uses
• The virtual proxy example from ET++ text building block
classes.
• NEXTSTEP: uses proxies (instances of class NXProxy)as local
representatives for objects that may be distributed.
▪ Server creates proxies for remote objects when
clients request them.
▪ On receiving a message, the proxy encodes it
along with its arguments and then forward s the
encoded message to the remote subject.
Related Patterns
1. Adapter ( 139) :
⮚ An adapter provides a different interface to the object it adapts. In
contrast,
⮚ a proxy provides the same interface as its subject.
⮚ a proxy used for access protection might refuse to perform an
operation that the subject will perform ,so its interface may be
effectively a subset of the subject's.
2. Decorator (175):
⮚ Although decorators can have similar implementations as proxies,
decorators have a different purpose.
⮚ A decorator adds one or more responsibilities to an object, whereas a
proxy controls access to an object.