02 Structural Design Patterns 2 Moshe Fresko BarIlan
02 - Structural Design Patterns – 2 Moshe Fresko Bar-Ilan University תשס"ח 2008
Flyweight Moshe Fresko Bar-Ilan University תשס"ו - 2005 -2006 Design Patterns Course
Flyweight l l Intent: Use sharing to support large number of fine-grained objects efficiently. Motivation l l l 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 l l l 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. l Intrinsic state is stored in the Flyweight, and is independent of the context. § l 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 l The Flyweight pattern’s effectiveness depends on where and how it’s used. Use it when: l l l 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 l Flyweight l l Concrete. Flyweight l l Not all Flyweight subclasses need be shared. Flyweight. Factory l l Implements the Flyweight interface and adds storage for intrinsic state, if any. Unshared. Concrete. Flyweight l l Declares an interface through which flyweights can act on extrinsic state. Creates and manages flyweight objects and their sharing. Client l Maintains a reference to flyweight and stores the extrinsic state
Flyweight – Implementation l Removing Extrinsic State l l 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 l l 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.
String. Example class String. Example { public static void main(String[]args) { String ent 1 = new String("This is a string") ; String ent 2 = new String("This is another string") ; String ent 3 = new String("This is another string") ; if (ent 2==ent 3) System. out. println("ent 2 and ent 3: same String ref. ") ; else System. out. println("ent 2 and ent 3: different String ref. ") ; } }
Unique String import java. util. * ; interface Entity { public String get. Name() ; } class Entity. Factory { static class Entity. Wrapper implements Entity { String str = null ; public Entity. Wrapper(String str) { this. str = str ; } public String get. Name() { return str ; } } private static Map map = new Hash. Map() ; public static Entity get. By. Name(String str) { if (! map. contains. Key(str)) map. put(str, str) ; return new Entity. Wrapper((String)map. get(str)) ; } public static int get. Size() { return map. size() ; } }
Unique String class Unique. String { public static void main(String[]args) { Entity ent 1 = Entity. Factory. get. By. Name("This is a string"); Entity ent 2 = Entity. Factory. get. By. Name("This is another string"); Entity ent 3 = Entity. Factory. get. By. Name("This is another string"); ; } System. out. println("# of Strings in Memory is "+ Entity. Factory. get. Size()) ; if (ent 2. get. Name()==ent 3. get. Name()) System. out. println("ent 2 and ent 3: same String ref. ") ; else System. out. println("ent 2 and ent 3: different String ref. ") } Output: # of Strings in Memory is 2 ent 2 and ent 3: same String ref.
Proxy Moshe Fresko Bar-Ilan University תשס"ו - 2005 -2006 Design Patterns Course
Proxy l l Intent: Provide a surrogate or placeholder for another object to control access to it Motivation: l 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 and Types 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: l l 1. 2. 3. 4. Remote proxy: Provides a local representative for an object in a different address space. Virtual proxy: Creates expensive objects on demand. Protection proxy: Controls access to original objects. Smart reference: Replacement for a bare pointer. l Counting the number of references to the real object. l Loading an object into memory when it is first accessed. l Checking that the real object is locked (unchangeable).
Proxy – Structure
Proxy - Participants l Proxy l l Subject l l 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 Defines the common interface for real Subject and Proxy Real. Subject l Defines the real object that the proxy represents
Proxy – Consequences Proxy forwards requests to Real Subject when appropriate l 1. 2. 3. l A remote proxy can hide the fact that the object resides in a different address space. A virtual proxy can perform optimization by creating the object on demand. Protection proxies and smart references allow additional housekeeping. Copy-on-write can be hidden from client.
Unique String with Ref Count class Entity. Factory { private static Map map = new Hash. Map() ; private static void remove. Str(String str) { map. remove(str) ; } static class Ref. Counted. Entity { private String str; private int cnt; Ref. Counted. Entity(String str) { this. str=str ; cnt=0 ; } public void incr() { cnt++ ; } public void decr() { if ((--cnt)==0) remove. Str(str) ; } public String get. Name() { return str ; } }. . . }
Unique String with Ref Count class Entity. Factory {. . . static class Entity. Wrapper implements Entity { Ref. Counted. Entity ref = null ; public Entity. Wrapper(Ref. Counted. Entity ref) { this. ref = ref ; ref. incr() ; } public String get. Name() { return ref. get. Name() ; } public void finalize() { ref. decr() ; } } public static Entity get. By. Name(String str) { if (! map. contains. Key(str)) map. put(str, new Ref. Counted. Entity(str)) ; return new Entity. Wrapper((Ref. Counted. Entity)map. get(str)) ; } public static int get. Size() { return map. size() ; } }
Unique String with Ref Count class Unique. String. Ref { public static void main(String[]args) { Entity ent 1 = Entity. Factory. get. By. Name("This is a string") ; Entity ent 2 = Entity. Factory. get. By. Name("This is another string") ; Entity ent 3 = Entity. Factory. get. By. Name("This is another string") ; System. out. println("# of Strings in Memory is "+Entity. Factory. get. Size()) ; if (ent 2. get. Name()==ent 3. get. Name()) System. out. println("ent 2 and ent 3: same String ref. ") ; else System. out. println("ent 2 and ent 3: different String ref. ") ; System. out. println("Clearing ent 1. . ") ; ent 1 = null ; System. gc() ; System. out. println("# of Strings in Memory now is “ +Entity. Factory. get. Size()) ; } } Output: # of Strings in Memory is 2 ent 2 and ent 3: same String ref. Clearing ent 1. . # of Strings in Memory now is 1
- Slides: 25