Presentation is loading. Please wait.

Presentation is loading. Please wait.

Structural Pattern: Flyweight To maximize flexibility, it is often advantageous to model objects down to very fine levels of granularity. C h a p t e.

Similar presentations


Presentation on theme: "Structural Pattern: Flyweight To maximize flexibility, it is often advantageous to model objects down to very fine levels of granularity. C h a p t e."— Presentation transcript:

1

2 Structural Pattern: Flyweight To maximize flexibility, it is often advantageous to model objects down to very fine levels of granularity. C h a p t e r 4 – P a g e 109 However, when very large numbers of such objects are needed in an application, this level of granularity can be prohibitively expensive in terms of performance and memory usage. The Flyweight Pattern tackles this problem by splitting the objects into their extrinsic (i.e., state-dependent) and intrinsic (state-independent) components. The intrinsic parts are shared within the Flyweight object, while the extrinsic parts are controlled by the client and passed to the Flyweight as needed.

3 The Flyweight Pattern C h a p t e r 4 – P a g e 110 The Client maintains a reference to the Flyweight objects and computes or stores their extrinsic state. The FlyweightFactory creates and manages the Flyweight objects, ensuring proper sharing (i.e., if a client needs a Flyweight, the FlyweightFactory supplies an existing one or, if none exists, creates a new one). The Flyweight declares an interface through which the concrete Flyweight objects can deal with their extrinsic state. The ConcreteFlyweight implements the Flyweight interface and adds storage for its intrinsic state; although the Flyweight interface enables sharing, UnsharedConcreteFlyweight objects may exist.

4 Non-Software Flyweight Example The public switched telephone network is an example of a Flyweight. C h a p t e r 4 – P a g e 111 There are several resources (ConcreteFlyweights) such as dial tone generators, ringing generators, and digit receivers that must be shared between all subscribers. A subscriber (the Client) 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.

5 C++ Flyweight Pattern Example C h a p t e r 4 – P a g e 112 /* Network links are the Flyweight objects here, with the technology type being used (e.g., */ /* MPLS, BGP) as their intrinsic features and their adjacent nodes (types include core routers, */ /* provider-edge routers, and subscriber-edge routers), adjacent interfaces (types include IP, */ /* ATM, etc.), and IP address ranges as their extrinsic features. */ /* */ /* When each link in the network is capable of supporting several IP addresss, specific IP */ /* addresses must be assigned to the interfaces supported by the links between adjacent nodes, */ /* which, for elaborate networks, can become a prohibitive task. */ #include #include "RealLink.h" using namespace std; void main() { GenericLinkContext* aLinkContext = new GenericLinkContext(); RealLink* aLink = new RealLink("MPLS", "Core Router A", "Core Router B", "Interface IP", "Interface ATM", aLinkContext); RealLink* anotherLink = new RealLink("BGP", "Core Router X", "Edge Router Y", "Interface ATM", "Interface IP", aLinkContext); aLinkContext->SetAddressRange(anotherLink->mySlotNumber, " x", 6, 9); aLinkContext->SetAddressRange(aLink->mySlotNumber, " x", 0, 7); cout GetTechnologyType() << " link, the IP Address range is " GetAllIPAddresses() << endl << endl; cout GetTechnologyType() << " link, the IP Address range is " GetAllIPAddresses() << endl << endl; }

6 C h a p t e r 4 – P a g e 113 #include using namespace std; class GenericLinkContext { public: explicit GenericLinkContext() { SetNextFreeSlot(-1); } virtual ~GenericLinkContext() {} virtual int GetNextFreeSlot() { if (nextFreeSlot < MAX_ARRAY_LENGTH) return ++nextFreeSlot; else return nextFreeSlot; } virtual void SetNextFreeSlot(int theNextFreeSlot) { nextFreeSlot = theNextFreeSlot; } virtual void SetAddressRange(int slot, string baseAddress, int offset, int range) { AddressRangeArray[slot].baseRangeAddress = baseAddress; AddressRangeArray[slot].addressOffset = offset; AddressRangeArray[slot].addressRange = range; } virtual string GetBaseAddress(int slot) { return AddressRangeArray[slot].baseRangeAddress; } virtual int GetAddressOffset(int slot) { return AddressRangeArray[slot].addressOffset; } virtual int GetAddressRange(int slot) { return AddressRangeArray[slot].addressRange; } private: int nextFreeSlot; static const int MAX_ARRAY_LENGTH = 10; /* Each entry in the array AddressRangeArray stores the IP address range details */ /* for a given link. Each link has an associated slot in this array. So when a new */ /* link must be created with a specific IP address range, the nextFreeSlot value */ /* is retrieved by invoking GetNextFreeSlot(). If the value is less than the */ /* maximum (10), a new address range array slot will be allocated. Once this new */ /* slot is obtained, the IP address range can be supplied via SetAddressRange(). */ struct AddressRanges { string baseRangeAddress; int addressOffset; int addressRange; } AddressRangeArray[MAX_ARRAY_LENGTH]; };

7 C h a p t e r 4 – P a g e 114 #include "GenericLinkContext.h" #include using namespace std; class GenericLink { public: explicit GenericLink(GenericLinkContext* aLinkContext, string nodeA, string nodeB, string ifA, string ifB) { linkContext = aLinkContext; mySlotNumber = linkContext->GetNextFreeSlot(); NodeA = nodeA; NodeB = nodeB; InterfaceA = ifA; InterfaceB = ifB; } virtual ~GenericLink() {} protected: GenericLinkContext* linkContext; public: int mySlotNumber; private: string NodeA; string NodeB; string InterfaceA; // Each interface can support many IP addresses string InterfaceB; // Each interface can support many IP addresses };

8 C h a p t e r 4 – P a g e 115 #include "GenericLink.h" #include using namespace std; class RealLink : public GenericLink { public: explicit RealLink(string aTechnologyType, string nodeA, string nodeB, string ifA, string ifB, GenericLinkContext* aLinkContext): GenericLink(aLinkContext, nodeA, nodeB, ifA, ifB) { technologyType = aTechnologyType; } virtual ~RealLink() {} string GetAllIPAddresses() { string ipAddressRange = ""; int addressOffset = linkContext->GetAddressOffset(mySlotNumber); int addressRange = linkContext->GetAddressRange(mySlotNumber); ipAddressRange = ipAddressRange + linkContext->GetBaseAddress(mySlotNumber) + " - " + linkContext->GetBaseAddress(mySlotNumber); int index = 0; while (ipAddressRange[index] != 'x') index++; ipAddressRange[index] = addressOffset + '0'; while (ipAddressRange[index] != 'x') index++; ipAddressRange[index] = addressRange + '0'; return ipAddressRange; } string GetTechnologyType() { return technologyType; } private: string technologyType; };

9 Flyweight Pattern Advantages C h a p t e r 4 – P a g e 116 There are cases in programming where it seems that a very large number of small class instances is needed to represent data. Essentially, the variables that differ can be moved outside of the class instance and passed in as part of a method call. If the instances are fundamentally the same except for a few parameters, the number of instantiations can be greatly reduced by means of the Flyweight Pattern. While the Flyweight Pattern is not commonly used in application software, it does provide a useful technique for managing resources at the system level.


Download ppt "Structural Pattern: Flyweight To maximize flexibility, it is often advantageous to model objects down to very fine levels of granularity. C h a p t e."

Similar presentations


Ads by Google