gof design pattern categories - emadilms.ir · •sometimes a toolkit or class library can not be...
TRANSCRIPT
GoF Design Pattern Categories
Purpose
Creational Structural Behavioral
Scope Class Factory Method Adapter Interpreter
Template Method
Object Abstract Factory
Builder
Prototype
Singleton
Adapter
Bridge
Composite
Decorator
Facade
Proxy
Flyweight
Chain of Responsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor
Structural patterns
• Structural Patterns let you compose classes or objects into larger structures
Adapter Pattern
• Intent
• Convert the interface of a class into another interface clients expect.
• Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
• Wrap an existing class with a new interface.
• Also Known As
• Wrapper
Intermediary acts like a translator between the client and the
server. E.g., Format/protocol conversions.
Adapter Pattern Motivation
•Sometimes a toolkit or class library can not be used becauseits interface is incompatible with the interface required byan application
•We can not change the library interface, since we may nothave its source code
•Even if we did have the source code, we probably shouldnot change the library for each domain-specific application
Adapter Pattern
• Motivation
Structure
An object adapter relies on object composition:
• Delegation is used to bind an Adapter and an Adaptee
• 1) Interface inheritance is use to specify the interface of the
• Adapter class.
• 2) Adaptee, usually called legacy system, pre-exists the Adapter.
• 3) Target may be realized as an interface in Java.
Structure
An object adapter relies on object composition:
Structure
• A class adapter uses multiple inheritance to adapt one interface to another:
Adapter Pattern
• Applicability
• Use the Adapter pattern when
• you want to use an existing class, and its interface does not match the one you need.
• you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces.
• (object adapter only) you need to use several existing subclasses, but it's unpractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.
Participants
• Target (shape)
defines the domain-specific interface that Client uses.
• Adapter (TextShape)
adapts the interface Adaptee to the Target interface.
• Adaptee (TextView)
defines an existing interface that needs adapting.
• Client (DrawingEditor)
collaborates with objects conforming to the Target interface.
Collaboration
Clients call operations on an Adapter instance. In turn, the adaptercalls Adaptec operations that carry out the request.
Amirkabir University of Technoloy Computer Engineering
Departmentslide 16
Adapter Pattern
Consequences
Class form
commits to a concrete Adaptee class, so won’t work if we
want to adapt a class as well as subclasses (use object form)
Adapter can override Adaptee’s behavior
introduces only one object; no pointer indirection required
Adapter Pattern
Consequences
Object form
allows single Adapter to work with many Adaptee
subclasses; can add functionality to all Adaptees at once
harder to override Adaptee behvarior – have to subclass
Adaptee and make Adapter refer to the subclass
Implementation
• How much adapting should be done?
• Simple interface conversion that just changes operation names and order of arguments
• Totally different set of operations
• Does the adapter provide two-way transparency?
• A two-way adapter supports both the Target and the Adaptee interface. It allows an adapted object (Adapter) to appear as an Adaptee object or a Target object
Implementation
• Adapter should be subtype of Target
• Pluggable adapters should use the narrowest definition
• Abstract operations to minimize exposed interface
• Delegated objects to localize behavior
• Parameterized processing avoids subclasses of adaptee
Related pattern• The Bridge pattern shares structure with object adapter, but
diverges on intent.
• Bridge is concerned with separating an object's interface fromits implementation while adapter changes the interface of anexisting object
• The Decorator pattern does not change an object's interface,but it does support recursive composition which adapter doesnot.
• In this way, Decorator is more flexible than adapter fordealing with functionality additions
• Proxy defines surrogate for another object without changingits interface
Implementation
Amirkabir University of Technoloy Computer Engineering
Departmentslide 22
Adapter
• Now, let’s say you’re short on Duck objects and you’d liketo use some Turkey objects in their place.
• Obviously we can’t use the turkeys outright because theyhave a different interface.
• So, let’s write an Adapter:
class Adaptee
{
public string GetLastName()
{ return “Mahmoodi"; }
}
------------------
interface ITarget
{
string GetFullName();
}
class Adapter:Adaptee,ITarget
{
public string GetFullName()
{
//Adaptee a = new Adaptee();
return "Ali " + GetLastName();
}
}
----------
private void button1_Click(object sender, EventArgs e)
{
ITarget i = new Adapter();
MessageBox.Show(i.GetFullName());
}
Bridge pattern
• Also Known As
• Handle/Body
Motivation
• Problem: For some classes, we want to adapt (reuse) eithertheir abstractions, their implementations or both. How can westructure a class so that abstractions and/or implementationscan easily be modified.
• Inheritance binds an implementation to the abstractionpermanently, which makes it difficult to modify, extend, andreuse abstraction and implementations independently.
Applicability
• Need to avoid a permanent binding between an abstraction andimplementation.
• When abstractions and implementations should be extensiblethrough subclassing.
• When implementation changes should not impact clients.
• When the implementation should be completely hidden from theclient. (C++)
• When you have a proliferation of classes.
• When, unknown to the client, implementations are sharedamong objects
Structure
Participants & Collaborations
• Abstraction (Window)
- defines the abstraction's interface
- maintains a reference to the Implementor
forwards requests to the Implementor (collaboration)
• RefinedAbstraction ((IconWindow))
- extends abstraction interface
• Implementor (Windowlmp)
- defines interface for implementations
• ConcreteImplementor (XWindowImp, PMWindowImp)
-implements Implementor interface, ie defines animplementation
Consequences
• Decouples interface and implementation
Decoupling Abstraction and Implementor also eliminatescompile-time dependencies on implementation. Changingimplementation class does not require recompile of abstractionclasses.
• Improves extensibility
Both abstraction and implementations can be extendedindependently
•Hides implementation details from clients
Implementation Issues
• How, where, and when to decide which implementer to instantiate?
Depends: - if Abstraction knows about all concrete implementer, thenit can instantiate in the constructor.
- It can start with a default and change it later
- Or it can delegate the decision to another object (to an abstractfactory for example)
• Implementers can be shared and usage tracked. (Handle / Body)
• Can’t implement a true bridge using multiple inheritance
A class can inherit publicly from an abstraction and privately from animplementation, but since it is static inheritance it bind animplementation permanently to its interface
Example1
Suppose I have been given the task of writing a program that will
draw rectangles with either of two drawing programs. I have
been told that when I instantiate a rectangle, I will know whether
I should use drawing program 1 (DP1) or drawing program 2
(DP2).
The rectangles are defined as two pairs of points, as represented
in the following figures and the differences between the drawing
programs are summarized in the following table.
Example1
Example 1
My customer told me that the clients of the rectangles do not want toworry about what type of drawing program it should use. It occurs to methat since the rectangles are told what drawing program to use wheninstantiated, I can have two different kinds of rectangle objects: one thatuses DP1 and one that uses DP2. Each would have a draw method butwould implement it differently.
Example1By having an abstract class Rectangle, I take advantage of the fact
that the only difference between the different types of Rectangleare how they implement the drawLine method. The V1Rectangleis implemented by having a reference to a DP1 object and usingthat object’s draw_a_line method. The V2Rectangle isimplemented by having a reference to a DP2 object and using thatobject’s drawline method. However, by instantiating the righttype of Rectangle, I no longer have to worry about this difference.
Example 1Java Code Fragments
Example 1
Now, suppose that after completing this code, one of the inevitablerequirements three (death, taxes, and changing requirements) comes myway. I am asked to support another kind of shape—this time, a circle.However, I am also given the mandate that the collection object does notwant to know the difference between Rectangles and Circles.
It occurs to me that I can simply extend the approach I’ve already startedby adding another level to my class hierarchy. I only need to add a newclass, called Shape, from which I will derive the Rectangle and Circleclasses. This way, the Client object can just refer to Shape objectswithout worrying about what kind of Shape it has been given.
As a beginning object-oriented analyst, it might seem natural to implementthese requirements using only inheritance. For example, I could start outwith something like the following figure and then, for each kind ofShape, implement the shape with each drawing program, deriving aversion of DP1 and a version of DP2 for Rectangle and deriving aversion of DP1 and a version of DP2 one for Circle.
Example1
Example1
•The combinatorial problemLook at the previous class diagram and pay attention to the third row of
classes. Consider the following:
- The classes in this row represent the four specific types of Shapes that I have. What happens if I get another drawing program, that is, another variation in implementation? I will have six different kinds of Shapes (two Shape concepts times three drawing programs).
- Imagine what happens if I then get another type of Shape, another variation in concept. I will have nine different types of Shapes (three
Shape concepts times three drawing programs).
.
Example1
The class explosion problem arises because in this solution, the couplingabstraction (the kinds of Shapes) and the implementation (the drawingprograms) are tightly coupled.
Each type of shape must know what type of drawing program it is using. Ineed a way to separate the variations in abstraction from the variations inimplementation so that the number of classes only grows linearly
Example1
This is exactly the intent of the Bridge pattern: [to] de-couple anabstraction from its implementation so that the two can varyindependently.2
Example 1
Question: What else is poor about this design?
• Does there appear to be redundancy?
• Would you say things have high cohesion or low cohesion?
• Are things tightly or loosely coupled?
• Would you want to have to maintain this code?
Example1 The overuse of inheritance.
As a beginning object-oriented analyst, I had a tendency to solve
the kind of problem I have seen here by using special cases,
taking advantage of inheritance. I loved the idea of inheritance
because it seemed new and powerful. I used it whenever I could.
This seems to be normal for many beginning analysts, but it is
naive: given this new “hammer,” everything seems like a nail.
Example1
• An alternative approach
May be we used the wrong type of inheritance hierarchy? Is this one any better?
Example1
Example1
The characteristics of the problem fit this nicely. I know that I ought
to be using the Bridge pattern even though I do not know yet how to
implement it.
Example1
• You have to do two things first.
1- Commonality analysis
2-Variablity analysis
The common concepts will be represented by abstract classes , variations will be implemented by concrete classes.
Example1
In this case we different types of shapes and different type of drawing
programs. So common concepts are shape and Drawing. So we
encapsulate them
Example1
The next step is to represent the specific variations that are present. For Shape, rectangles and circles. For drawing programs,DP1 and DP2 respectively.
Example1 • Lets see if we can relate these classes by having one use the
other. Two possibilities: either Shape uses the Drawing programs or the Drawing programs use Shape.
If drawing programs could draw shapes directly, then they would have to know some things about shapes in general: what they are, what they look like. But this violates a fundamental principle of objects: an object should only be responsible for itself.
• It also violates encapsulation. Drawing objects would have to know specific information about the Shapes (that is, the kind of Shape) in order to draw them.
Example1
• Now, consider the first case. Shapes use Drawing objects to draw themselves. Shapes wouldn’t need to know what type of Drawing object it used since I could have Shapes refer to the Drawing class.
Example1
Example1
Added protected methods in shape that call methods in Drawing
.
Example1- Java code fragments
Java code for example1
Java code exmple1
Java Code for Example1
Java code for Example1
Java code for Example1
Design Patterns - Bridge Pattern Example
Car
Ford Toyota Sporty Truck
SportyFord ToyotaTruck FordTruck SportyToyota
How can we simplify this design?
Design Patterns - Bridge Pattern Example
Ford ToyotaSporty Truck
Car CarManufacturer
Composite Pattern
• Intent
• Compose objects into tree structures to represent part-wholehierarchies.
• Composite lets clients treat individual objects andcompositions of objects uniformly.
Composite Pattern
•Motivation
Graphic applications let users build complex diagrams outof simple components.
A simple implementation can define a class for primitivesand other classes that act as containers for these.
Problem: The code that uses theses classes is forced totreat primitives and container objects differently.
Composite Pattern
• Motivation:
- Using Composite pattern clients do not need to make this distinction.
- Graphic, Line, Text, Picture
The key: The abstract class that represent both primitives and their containers.
Composite Pattern
Composite Pattern
Composite Pattern
• Applicability (use the pattern when…)
• You want to represent part-whole hierarchies of objects
• You want clients to be able to ignore the difference between compositions of objects and individual objects
Composite pattern
Structure:
Composite Pattern
• Participants
• Component (Graphic)
• Declares the interface for objects in the composition
• Implements default behavior for the interface common to all classes, as appropriate
• Declares an interface for accessing and managing its child components
• (Optional) Defines an interface for accessing a component’s parent in the recursive structure, and implements it if that’s appropriate
• Leaf (Line, Text, Rectangle)
• Represents the leaf objects in the composition. A leaf has no children
• Defines behavior for primitive objects in the composition.
Composite Pattern• Participants
• Composite (Picture)
• Defines behavior for components having children
• Stores child components.
• Implements child-related operations in the Component interface
• Client
• Manipulates objects in the composition through the Component interface
Composite Pattern
•Collaborations
Clients use the Component class interface to interact with all objects in the composite structures.
If the recipient is a leaf it is handled directly,
If it is a composite, it is passed to its children.
Composite Pattern
•Consequences
1- Wherever client code expects a primitive, it can also takea composite object
2- Makes the client simple
3- Makes it easy to add new kinds of components
4- Disadvantage: Sometimes you want a composite to haveonly certain components, you can not rely on type system toenforce those restrictions.
Composite Pattern• Implementation
• Explicit Parent ReferencesThe usual place to define the parent reference is in the
component class. The easiest way is to add and remove the reference when a leaf is added or removed from the composite
• Sharing Components• Share components to reduce storage requirements• Becomes difficult when? When a component can only have
one parent• Which pattern makes this easier? Flyweight
Composite Pattern• Implementation
• Maximizing the Component Interface• Component class should define as many common operations
for the Composite and Leaf classes as possibleHow returning children would be implemented for leaf for example?
• Declaring the Child Management OperationsTrade off between:
• Transparency vs Uniformity• Safety Clients may try to do meaningless things like add and
remove objects from leaves• It is better let component fail and raise an exception if it is not
allowed to add or remove children
Composite Pattern
Composite Pattern• Implementations (cont.)
• Should Component Implement a List of Components?• Child Ordering
• Sometimes it is useful to provide ordering. To do this just be careful when writing your Add/Remove children methods
• Iterator pattern (p257) comes in handy here• Caching to Improve Performance
• If caching is needed extra caching information should be stored in the Composite class
• Who Should Delete Components?• In a language without Garbage Collection its best to have
Composite responsible for deleting its children when it’s destroyed
Composite Pattern• Implementations (cont.)
• What’s the Best Data Structure for Storing Components?• Basically any will work (Linked List, trees, arrays, Hash
Tables, etc)• The trick to choosing will be (as per usual) the efficiency
trade-offs• Sometimes composites have a variable for each child, although
this requires each subclass of Composite to implement its own management interface. See Interpreter (p243) for an example.
Composite Pattern
• Known Uses
Almost all complex systems, MVC, every user interface toolkit or framework
• Related Patterns
Decorator is often used with composite,
Flyweight lets you share components, but they can not refer to their parents
Iterator can be used to traverse the composites
Visitor localizes operations and behaviors that otherwise be distributed across composite and leaf classes.
Example1• Situation: A GUI system has window objects which can contain various
GUI components (widgets) such as, buttons and text areas. A window can also contain widget container objects which can hold other widgets.
• Solution 1: What if we designed all the widgets with different interfaces for "updating" the screen? We would then have to write a Window update() method as follows:
Example 1
•Well, that looks particularly bad. If we want to add a new kind of widget, we have to modify the update() method of Window to handle it.
•Solution 2: We should always try to program to an interface, right? So, let's make all widgets support the Widget interface, either by being subclasses of a Widget class or implementing a Java Widget interface. Now our update() method becomes:
Example1
Example2
Example2
abstract class BaseShape
{
public string Name;
public abstract void Display();
}
-------------
class Shape:BaseShape
{
public override void Display()
{ MessageBox.Show(Name); }
}
-------------------
class CompositeShape:BaseShape
{
private List<BaseShape> ListShape = new List<BaseShape>();
public void add(BaseShape shape)
{ ListShape.Add(shape); }
public override void Display()
{
foreach (BaseShape sh in ListShape)
sh.Display();
}
}
private void button1_Click(object sender, EventArgs e)
{
shape line=new shape();
Line.name=“myline”;
Line.display()
}
یا -----------------------------------
private void button1_Click(object sender, EventArgs e)
{
Shape line1 = new Shape();
line1.Name = " ;"خط چپ
Shape line2 = new Shape();
Shape Line3 = new Shape();
Shape Line4 = new Shape();
line2.Name = " ;"خط راست
Line3.Name = " ;"خط باال
Line4.Name = " ;"خط پایین
CompositeShape c = new CompositeShape();
c.add(line1);
c.add(line2);
c.add(Line3);
c.add(Line4);
c.Display();
}
Decorator
• Intent
• Add additional responsibilities and functionality to objects dynamically
• Also known as Wrapper
• Example: a Text Window
Decorator
Decorator
Structure
Participants
• Component (VisualComponent)
- defines the interface for objects that can have responsibilitiesadded to them dynamically.
• ConcreteComponent (TextView)
- defines an object to which additional responsibilities can beattached.
• Decorator
- maintains a reference to a Component object and defines aninterface that conforms to Component's interface.
• ConcreteDecorator (BorderDecorator, ScrollDecorator)
- adds responsibilities to the component.
Decorator: Motivation & Application
• Subclassing can only add functionality at runtime
• Avoid enumerating all possible sub classes
• Such as adding a border function to text window.
• Use with optional functionality
Decorator: Structure
• Participants: Component, ConcreteComponent, Decorator, ConcreteDecorator
Decorator: Consequences
• Positives
• More flexibility than static inheritance
• Avoids feature laden classes high in hierarchy
• Negatives
• Lots of little objects
• Interface conformance
Essence of the Decorator pattern
• The essence of the Decorator pattern
• Linked list of object instances, first one calls next one, etc.
• Each object adds its particular computation (often, but not exclusively, visual) to the output before passing to next object
• It is possible to have multiple chains, each ending at the same terminal (or decorator) object
• Can pre-arrange commonly used decorator chains
Implementation details
• Need to know next object in chain
• Typically passed into the constructor
• Could have a separate method instead (would need to add this to IComponent
• May need to know details about terminal object
• Need to know position of spaceship to put shield directly in front, and exhaust directly in back
• Each object in list can be given reference to terminal object
• Use reference to spaceship object to retrieve its current location
• May need to remove a decorator
• E.g., shields no longer active
• Will need to write code that removes a decorator instance, and repairs the links among remaining ones
• If the removed decorator is the first in the chain, removal is easy
Problem: Magic system with variable effects
• Consider a game that has castles, fighters, wizards, and magic cars• Fighters can be inside castles
• Wizards have spells:• Some only affect the castle, weakening its walls (lightening bolt)
• Other, more powerful spells, weaken the walls and do damage to the people inside (fireball explosion)
• If the people inside the castle are inside a magic car, the car absorbs some, but not all, of the damage
• Need some way to have the applied damage vary depending on who is inside what • E.g., damage depends on containment
Design Patterns - Facade PatternFacade Pattern
1) Provides a unified interface to a set of objects in a subsystem.
A facade defines a higher-level interface that makes the
subsystem easier to use (i.e. it abstracts out the gory details)
2) Facades allow us to provide a closed architecture
Design Patterns - Facade PatternIntent
Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for extending
functionality.
Structure
Design Patterns - Open vs Closed Architecture
Open vs Closed Architecture
1) Open architecture:
Any dealer management system can call
any component or class operation of the
PAID databases.
2) Why is this good?
Efficiency
3) Why is this bad?
Can’t expect the client to understand how
the subsystem works or any of the
complex relationships that may exist
within the subsystem.
We can (pretty much) be assured that the
subsystem will be misused, leading to
non-portable code
Realizing a Closed Architecture with a Facade
Realizing a Closed Architecture with a
Facade
1) The subsystem decides exactly how it is
accessed.
2) No need to worry about misuse by
clients
3) If a façade is used the subsystem can be
used in an early integration
We need to write only a driver
Decorator Pattern - Motivation
• Widget Example• Suppose you have a user interface toolkit and you wish to make a border or scrolling
feature available to clients without defining new subclasses of all existing classes.
• The client "attaches" the border or scrolling responsibility to only those objects requiring these capabilities.
• Stream Example• cascading responsibilities on to an output stream
Decorator Pattern - implementation
• Consider the followi ng issues when implementing a facade:
1. Reducing client-subsystem coupling.
2. Public versus private subsystem classes.
• Related pattern:
• Abstract Factory can be used with Facade to provide an interface for creating subsystem objects in a subsystem-independent way.
• Abstract Factory can also be used as an alternative to Facade to hide platform-specific classes.
Decorator Pattern - implementation
• Related pattern:
• Mediator is similar to Facade in that it abstracts functionality of existing classes.
• However, Mediator's purpose is to abstract arbitrary communication betweencolleague objects, often centralizing functionality that doesn't belong in any oneo f them.
• A mediator's colleagues are aware of and communicate with the mediatorinstead of communicating with each other directly.
• In contrast, a façade merely abstracts the interface to subsystem objects to makethem easier to use; it doesn't define new functionality, and subsystem classesdon't know about it.
• Usually only one Facade object is required. Thus Facade objects are oftenSingletons
Decorator Pattern - Motivation
Decorator subclasses are free to add operations for specific functionality.
For example, ScrollDecorator's ScrollTo operation lets other objects scroll the
interface if they know there happens to be a ScrollDecorator object in the
interface.
TextViewdraw()
Decorator
VisualComponentdraw()
+componentcomponent.draw()
ScrollDecoratorscrollPosition
draw()scrollto()
BorderDecoratorborderWidth
draw()drawBorder()
super.draw()drawBorder()
draw()
Decorator Pattern - Motivation
Painting ExampleAlthough paintings can be hung on a wall with or without frames, frames are
often added, and it is the frame which is actually hung on the wall.
Prior to hanging, the paintings may be matted and framed, with the painting, matting, and frame forming a single visual
Decorator Pattern – Example(TestEoF.java)
Proxy Pattern - Motivation
What is expensive?
Object CreationObject Initialization
Defer creation and initialization to the time you need the object
Reduce the cost of access to objectsUse another object (“the proxy”) that acts as a stand-in for the
real objectThe proxy creates the real object only if the user asks for it
The Proxy Pattern• Intent
- Provide a surrogate or placeholder for another object to controlaccess to it
• Also Known As
- Surrogate
• Motivation
- A proxy is
a person authorized to act for another person an agent or substitute theauthority to act for another
- There are situations in which a client does not or can not reference anobject directly, but wants to still interact with the object.
- A proxy object : intermediary between the client and the target
object
179
• Motivation
- The proxy object : the same interface as the target object
- The proxy holds a reference to the target object and can forward requests to the target as required (delegation!)
• Applicability
- Proxies are useful wherever there is a need for a more sophisticated reference to a object than a simple pointer or simple reference can provide
180
The Proxy Pattern
ExampleThe Proxy provides a surrogate or place holder to provide access to an object.
A check or bank draft is a proxy for funds in an account.
A check can be used in place of cash for making purchases and ultimately controls access to cash in the issuer's account.
The Proxy Pattern
The Proxy Pattern
The Proxy Pattern: Applicability
• A remote proxy provides a local representative for an object in a different address space.
• A virtual proxy creates expensive objects on demand. The ImageProxy described in the Motivation is an example of such a proxy.
• A protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights. For example, KernelProxies in the Choices operating system provide protected access to operating system objects.
The Proxy Pattern: Applicability
• A smart reference is a replacement f o r a bare pointer that performs additional actions when an object is accessed. Typical uses include:
• counting the number of references to the real object so that it can be freed automatically when there are no more references (also called smart pointers ).
• loading a persistent object into memory when it's first referenced.
• checking that the real object is locked before it's accessed to ensure that no other object can change it.
The Proxy Pattern: structure
The Proxy Pattern: structure
The Proxy Pattern: structure
The Proxy Pattern: structure
• Types of Proxies
- Remote Proxy - Provides a reference to an object located in a different
address space on the same or different machine
- Virtual Proxy - Allows the creation of a memory intensive object on
demand. The object will not be created until it is really needed.
- Copy-On-Write Proxy - Defers copying (cloning) a target object until
required by client actions. Really a form of virtual proxy.
- Protection (Access) Proxy - Provides different clients with differentlevels of access to a target object
-
192
The Proxy Pattern
• Types of Proxies
- Cache Proxy - Provides temporary storage of the results of expensivetarget operations so that multiple clients can share the results
- Firewall Proxy - Protects targets from bad clients
- Synchronization Proxy - Provides multiple accesses to a target object
- Smart Reference Proxy - Provides additional actions whenever a target
object is referenced such as counting the number of references to theobject
193
The Proxy Pattern
Copy-On-Write Proxy Example
• Scenario: Suppose we have a large collection object, such as a hash table,which multiple clients want to access concurrently.
• One of the clients wants to perform a series of consecutive fetch operationswhile not letting any other client add or remove elements.
• Solution 1: Use the collection's lock object. Have the clientimplement a method which obtains the lock, performs its fetches and
then releases the lock.
• For example:
public void doFetches(Hashtable ht)
{
synchronized(ht) { // Do fetches using ht reference.}
}
• But this method may require holding the collection object's lock for a longperiod of time, thus preventing other threads from accessing the collection
196
• Solution 2: Have the client clone the collection prior to performing its fetchoperations. It is assumed that the collection object is cloneable and provides aclone method that performs a sufficiently deep copy.
• For example, java.util.Hashtable provides a clone method that makes a copyof the hash table itself, but not the key and value objects.
The doFetches() method is now:
public void doFetches(Hashtable ht) {
Hashtable newht = (Hashtable) ht.clone();
// Do fetches using newht reference.
}
197
Copy-On-Write Proxy Example
• The collection lock is held while the clone is being created. But once the clone iscreated, the fetch operations are done on the cloned copy, without holding theoriginal collection lock.
• But if no other client modifies the collection while the fetch operations are beingdone, the expensive clone operation was a wasted effort!
• Solution 3: clone the collection only when we need to, that is when some otherclient has modified the collection. For example, it would be great if the client thatwants to do a series of fetches could invoke the clone() method, but no actualcopy of the collection would be made until some other client modifies thecollection.
• This is a copy-on-write cloning operation.
• implement this solution using proxies
198
Copy-On-Write Proxy Example
• The proxy is the class Large Hashtable. When the proxy's clone() method isinvoked, it returns a copy of the proxy and both proxies refer to the same hashtable. When one of the proxies modifies the hash table, the hash table itself iscloned.
• The ReferenceCountedHashTable class is used to let the proxies know they areworking with a shared hash table . This class keeps track of the number of proxiesusing the shared hash table.
199
Copy-On-Write Proxy Example
• Scenario: An Internet Service Provider notices that many of its clients arefrequently accessing the same web pages, resulting in multiple copies of the webdocuments being transmitted through its server. What can the ISP do to improvethis situation?
• Solution: Use a Cache Proxy!
• The ISP's server can cache recently accessed pages and when a client requestarrives, the server can check to see if the document is already in the cache andthen return the cached copy. The ISP's server accesses the target web server onlyif the requested document is not in the cache or is out of date.
200
Cash Proxy Example
Synchronization Proxy Example
• Scenario: A class library provides a Table class, but does not provide acapability to allow clients to lock individual table rows.
We do not have the source code for this class library, but we have completedocumentation and know the interface of the Table class. How can we providea row locking capability for the Table class?
• Solution: Use a Synchronization Proxy!
202
First part of the Table class, just so we can see its interface:
public class Table implements ITable {
...
public Object getElementAt(int row, int column) {
// Get the element.
}
public void setElementAt(Object element, int row,
int column ) {
// Set the element.
}
public int getNumberOfRows() {return numrows;}
}
203
• Here is the table proxy:
public class RowLockTableProxy implements ITable {
Table realTable;
Integer[] locks;
public RowLockTableProxy(Table toLock) {
realTable = toLock;
locks = new Integer[toLock.getNumberOfRows()];
for (int row = 0; row < toLock.getNumberOfRows(); row++)
locks[row] = new Integer(row);
}
204
Synchronization Proxy Example
public Object getElementAt(int row, int column) {
synchronized (locks[row]) {
return realTable.getElementAt(row, column);
}
}
public void setElementAt(Object element, int row, int column) {
synchronized (locks[row]) {
return realTable.setElementAt(element, row, column);
}
}
public int getNumberOfRows() {
return realTable.getNumberOfRows();
}
}
205
Synchronization Proxy Example
Virtual Proxy Example
• Scenario: A Java applet has some very large classes which take a
long time for a browser to download from a web server. How can
we delay the downloading of these classes so that the applet starts
as quickly as possible?
• Solution: Use a Virtual Proxy!
• When using a Virtual Proxy:
- All classes other than the proxy itself must access the target class indirectly
through the proxy. If any class makes a static reference to the target class,
the Java Virtual Machine will cause the class to be downloaded. This is
true even if no instantiation of the target class is done.
206
• When using a Virtual Proxy (Continued):
- Even the proxy can not make a static reference to the target class initially.
So how does the proxy reference the target class? It must use some form of
dynamic reference to the target. A dynamic reference encapsulates the
target class name in a string so that the Java compiler does not actually see
any reference to the target class and does not generate code to have the
JVM download the class.
The proxy can then use the new Reflection API to create an instance of thetarget class.
207
Virtual Proxy Example
• Suppose one of the large classes is called LargeClass. It implements the
ILargeClass interface as shown here:
// The ILargeClass interface.
public interface ILargeClass {
public void method1();
public void method2();
}
// The LargeClass class.
public class LargeClass implements ILargeClass {
private String title;
public LargeClass(String title) {this.title = title;}
public void method1() {// Do method1 stuff.}
public void method2() {// Do method2 stuff.}
}
208
Virtual Proxy Example
• Here's the proxy class:
// The LargeClassProxy class.
public class LargeClassProxy implements ILargeClass {
private ILargeClass largeClass = null;
private String title;
// Constructor
public LargeClassProxy(String title) {
this.title = title;
}
// Method 1. Create LargeClass instance if needed.
public void method1() {
if (largeClass == null)
largeClass = createLargeClass();
largeClass.method1();
}
209
Virtual Proxy Example
// Method 2. Create LargeClass instance if needed.
public void method2() {
if (largeClass == null)
largeClass = createLargeClass();
largeClass.method2();
}
// Private method to create the LargeClass instance.
private ILargeClass createLargeClass() {
ILargeClass lc = null;
try {
// Get Class object for LargeClass.
// When we do this, the class will be downloaded.
Class c = Class.forName("LargeClass");
// Get Class objects for the LargeClass(String) constructor
// arguments.
Class[] args = new Class[] {String.class};
210
Virtual Proxy Example
// Get the LargeClass(String) constructor.
Constructor cons = c.getConstructor(args);
// Create the instance of LargeClass.
Object[] actualArgs = new Object[] {title};
lc = (ILargeClass) cons.newInstance(actualArgs);
System.out.println("Creating instance of LargeClass");
}
catch (Exception e) {
System.out.println("Exception: " + e);
}
return lc;
}
}
211
Virtual Proxy Example
• Here's a typical client:
// Client of LargeClass.
public class Client {
public static void main(String args[]) {
// Create a LargeClass proxy.
ILargeClass lc = new LargeClassProxy("Title");
// Do other things...
System.out.println("Doing other things...");
// Now invoke a method of LargeClass.
// The proxy will create it.
lc.method1();
}
}
212
Virtual Proxy Example
• Scenario: A machine at the College of OOAD has several utility servicesrunning as daemons on well-known ports. We want to be able to accessthese services from various client machines as if they were local objects.How can this be accomplished?
• Solution: Use a Remote Proxy!
• This is the essence of modern distributed object technology such as RMI,CORBA and Jini
213
Flyweight pattern
• Intent
• Use sharing to support large numbers of fine-grained objectsefficiently.
• Motivation
• Some applications could benefit from using objects throughout their design, but a naive implementation would be prohibitively expensive.
Flyweight pattern
Flyweight pattern
• Object structure
Flyweight pattern
• Object shaing
Flyweight pattern
Flyweight pattern
• Apply the Flyweight pattern when all of the following are true:
• An application uses a large number of objects.
• Storage costs are high because of the sheer quantity of objects.
• Most object state can be made extrinsic.
• Many groups of objects may be replaced by relatively few sharedobjects once extrinsic state is removed.
• The application doesn't depend on object identity. Since flyweightobjects may be seared, identity test will return true for conceptuallydistinct objects.
Flyweight pattern
Flyweight pattern
Flyweight pattern
• Participants
• Flyweight : declares the interface that flyweights use to acton extrinsic state.
• ConcreteFlyweight : implements the flyweight and addsstorage for the intrinsic state (which should be sharable).
• UnsharedConcreteFlyweight: not all flyweight need to beshared.
• FlyweightFactory: creates and manages flyweightobjects.ensures that flyweights are shared properly.
• Client: stores the extrinsic state of the flyweights.
•
Flyweight pattern• Collaborations
• State that a flyweight needs to function must becharacterized as either intrinsic or extrinsic.
Intrinsic state is stored in the Concrete Flyweight object;
Extrinsic state is stored or computed by Client objects. Clientspass this state to the flyweight when they invoke itsoperations.
• Clients should not instantiate ConcreteFlyweights directly.Clients must obtain ConcreteFlyweight objects exclusivelyfrom the FlyweightFactory object to ensure they are sharedproperly.
Flyweight pattern
• Consequences
• By increasing the amount of data that is shared, we can
increase our savings in space (memory, disk, etc).
• This saving is heavily influenced by the number of flyweight
we need to create.
• However, the use of Flyweights may introduce some
performance overhead.
• Since some data is stored outside the object, there are some
performance penalties (retrieving that data).
Implementationtern
• Consequences
• Removing extrinsic state :The first step when building a
flyweight is to decide what data should be intrinsic and what
data should be extrinsic. This decision is critical since it will
heavily influence the flyweight's performance.
• Managing shared objects: Because objects are shared, clients
shouldn't instantiate them directly. FlyweightFactory lets
clients locate a particular flyweight.
Flyweight pattern
• Example: Car Registrations
• Categorizing an object’s data as intrinsic or extrinsic: the
physical car data ( model, year) is intrinsic, and the owner
data (owner name, tag number, last registration date) is
extrinsic. This means that only one car object is needed for
each combination of model, and year.
Flyweight pattern
• Example: Car Registrations
• Imagine that you need to create a system to represent all of
the cars in a city. You need to store the details about each car
( model, and year) and the details about each car’s ownership
(owner name, tag number, last registration date).
Flyweight pattern
• Example: Car Registrations
• Instantiation Using a Factory: Factory ensures that only a
single copy of each unique intrinsic state is created:
Flyweight pattern• Example: Car Registrations
• Extrinsic State Encapsulated in a Manager: All of the data that
was removed from the Car objects has to be stored somewhere;
you use a singleton as a manager to encapsulate that data.
Flyweight pattern• Example: Lexi case study
• BTree
•
Flyweight pattern• Example: Folder Objects
• Suppose we want to draw a small folder icon with a name
under it for each person in an organization. they are actually
all the same graphical image. Even if we have two icons-one
for "is Selected" and one for "not Selected“-the number of
different icons is small.
Flyweight Pattern
Example: Folder Objects
class Folder{
public Folder(Color c){
color = c;
}
public void Draw(Graphics g, int tx, int ty, String name){
//draw folder
}
}
class FolderFactory{
Folder unSelected, Selected;
public FolderFactory(){
Selected = new Folder(Color.brown);
unSelected = new Folder(Color.yellow);
{
public Folder getFolder(boolean isSelected)}
if (isSelected)
return Selected;
else
return unSelected;
{
{
Flyweight Pattern
Example: Folder Objects
public void FolderFactory ::paint(Graphics g){
Folder f;
String name;
//go through all the names and folders
for (int i = 0; i< names.size(); i++)}
name = (String)names.elementAt(i);
if(name.equals(selectedName))
f = fact.getFolder(true);
else
f = fact.getFolder(false);
//have that folder draw itself at this spot
f.Draw(g, x, row, name);
//-----------
}
}
Flyweight Pattern – Example The Flyweight uses sharing to support large numbers of objects
efficiently
Example: The public switched telephone networkThere are several resources such as dial tone generators, ringing generators,
and digit receivers that must be shared between all subscribers.
A subscriber is unaware of how many resources are in the pool when he or she lifts the handset to make a call.
All that matters to subscribers is that a dial tone is provided, digits are received, and the call is completed.