Upload
madeline-jemima-horton
View
214
Download
2
Embed Size (px)
Citation preview
02 - Structural Design Patterns – 2
Moshe Fresko
Bar-Ilan University
תשס"ח
2008
Flyweight
Moshe Fresko
Bar-Ilan University
2005-2006 - תשס"ו
Design Patterns Course
Flyweight
Intent: Use sharing to support large number of fine-grained objects efficiently.
Motivation An Object Oriented Document editor implementation
may have objects representing each character. Even a moderate sized Document may need lots of
character objects. The Flyweight pattern describes how to share objects
to allow their use at fine granularities.
Flyweight - Motivation
Flyweight
A Flyweight is a shared object that can be used in multiple contexts simultaneously
Indistinguishable from a non-shared object Key concept is to distinguish between intrinsic and
extrinsic state. Intrinsic state is stored in the Flyweight, and is
independent of the context. Example: Character code, and its graphical style.
Extrinsic state depends on the context and thus it cannot be shared Coordinate position, character’s typographic style.
Flyweight
Flyweight – Motivation
Flyweight – Applicability
The Flyweight pattern’s effectiveness depends on where and how it’s used. Use it when: An application uses a large number of objects Storage costs are high because of sheer quantity
of objects Most object state can be made Extrinsic Many groups of objects may be replaced by
relatively few shared objects once extrinsic state is removed
The application doesn’t depend on object identity.
Flyweight – Structure
Flyweight – Structure
Flyweight – Participants Flyweight
Declares an interface through which flyweights can act on extrinsic state.
ConcreteFlyweight Implements the Flyweight interface and adds storage for
intrinsic state, if any. UnsharedConcreteFlyweight
Not all Flyweight subclasses need be shared. FlyweightFactory
Creates and manages flyweight objects and their sharing. Client
Maintains a reference to flyweight and stores the extrinsic state
Flyweight – Implementation
Removing Extrinsic State The pattern’s applicability is determined largely by
how easy it is to identify the extrinsic state and remove it from shared objects.
Managing Shared Objects Clients shouldn’t instantiate the objects directly.
Flyweight factory uses an associative store to locate existing objects.
Reference counting and Garbage Collection may be needed if an object is no longer in use. This is not necessary if the number of objects is fixed and small.
StringExample
class StringExample { public static void main(String[]args) { String ent1 = new String("This is a string") ; String ent2 = new String("This is another string") ; String ent3 = new String("This is another string") ;
if (ent2==ent3) System.out.println("ent2 and ent3: same String ref.") ; else System.out.println("ent2 and ent3: different String ref.") ; }}
Unique Stringimport java.util.* ;
interface Entity { public String getName() ;}
class EntityFactory { static class EntityWrapper implements Entity {
String str = null ; public EntityWrapper(String str) { this.str = str ; } public String getName() { return str ; } } private static Map map = new HashMap() ; public static Entity getByName(String str) { if (! map.containsKey(str)) map.put(str,str) ; return new EntityWrapper((String)map.get(str)) ; } public static int getSize() { return map.size() ; }}
Unique Stringclass UniqueString { public static void main(String[]args) { Entity ent1 = EntityFactory.getByName("This is a string"); Entity ent2 = EntityFactory.getByName("This is another
string"); Entity ent3 = EntityFactory.getByName("This is another
string");
System.out.println("# of Strings in Memory is "+ EntityFactory.getSize()) ; if (ent2.getName()==ent3.getName()) System.out.println("ent2 and ent3: same String ref.") ; else System.out.println("ent2 and ent3: different String
ref.") ; }}Output:# of Strings in Memory is 2ent2 and ent3: same String ref.
Proxy
Moshe Fresko
Bar-Ilan University
2005-2006 - תשס"ו
Design Patterns Course
Proxy
Intent: Provide a surrogate or placeholder for another object to control access to it
Motivation: On-demand creation. Like a document editor having
expensive-to-create graphical objects. A proxy can be stand-in for the real image object.
Proxy – Motivation
Applicability andTypes of Proxy Patterns Proxy is applicable whenever there is a need for a
more versatile or sophisticated reference to an object than a simple pointer.
Some example cases are:1. Remote proxy: Provides a local representative for an
object in a different address space.2. Virtual proxy: Creates expensive objects on demand.3. Protection proxy: Controls access to original objects.4. Smart reference: Replacement for a bare pointer.
Counting the number of references to the real object. Loading an object into memory when it is first accessed. Checking that the real object is locked (unchangeable).
Proxy – Structure
Proxy - Participants
Proxy Maintains a reference to the real subject Provides interface for the subject so that it can be
substituted with the subject Control access to the real subject
Subject Defines the common interface for real Subject
and Proxy RealSubject
Defines the real object that the proxy represents
Proxy – Consequences
Proxy forwards requests to Real Subject when appropriate
1. A remote proxy can hide the fact that the object resides in a different address space.
2. A virtual proxy can perform optimization by creating the object on demand.
3. Protection proxies and smart references allow additional housekeeping.
Copy-on-write can be hidden from client.
Unique String with Ref Count
class EntityFactory { private static Map map = new HashMap() ; private static void removeStr(String str) { map.remove(str) ; } static class RefCountedEntity { private String str; private int cnt; RefCountedEntity(String str) { this.str=str ; cnt=0 ; } public void incr() { cnt++ ; } public void decr() { if ((--cnt)==0) removeStr(str) ; } public String getName() { return str ; } } ...}
Unique String with Ref Count
class EntityFactory { ... static class EntityWrapper implements Entity { RefCountedEntity ref = null ; public EntityWrapper(RefCountedEntity ref) { this.ref = ref ; ref.incr() ; } public String getName() { return ref.getName() ; } public void finalize() { ref.decr() ; } } public static Entity getByName(String str) { if (! map.containsKey(str)) map.put(str,new RefCountedEntity(str)) ; return new EntityWrapper((RefCountedEntity)map.get(str)) ; } public static int getSize() { return map.size() ; }}
Unique String with Ref Count
class UniqueStringRef { public static void main(String[]args) { Entity ent1 = EntityFactory.getByName("This is a string") ; Entity ent2 = EntityFactory.getByName("This is another string") ; Entity ent3 = EntityFactory.getByName("This is another string") ;
System.out.println("# of Strings in Memory is "+EntityFactory.getSize()) ; if (ent2.getName()==ent3.getName()) System.out.println("ent2 and ent3: same String ref.") ; else System.out.println("ent2 and ent3: different String ref.") ;
System.out.println("Clearing ent1..") ; ent1 = null ; System.gc() ; System.out.println("# of Strings in Memory now is “ +EntityFactory.getSize()) ; }}
Output:# of Strings in Memory is 2ent2 and ent3: same String ref.Clearing ent1..# of Strings in Memory now is 1