Flyweight Docpdf
Flyweight Docpdf
FLYWEIGHT
DESCRIPTION
Every object can be viewed as consisting of one or both of the following two
sets of information:
1 There exists only one object of a given flyweight kind and is shared by
all the other appropriate objects.
2 Client objects should not be allowed to create flyweight instances
directly. At the same time, client objects should have a way of accessing
a required )O\ZHLJKW object when needed.
When the Flyweight pattern is applied, it is important to make sure that the
requirements listed in Table 17.1 are satisfied.
DESIGN HIGHLIGHTS
1..*
Flyweight
lstFlyweight:HashMap
intrinsic_var_1
...
intrinsic_var_n
synchronized getFlyweight(flyweightType)
:Flyweight
-Flyweight()
The flyweight design discussed so far meets the requirements listed in Table
17.1. In general, a flyweight is designed solely to represent the intrinsic state of
an object. Besides representing an object’s intrinsic state, the flyweight contains
the required data structures and the implementation to maintain different types
of singleton )O\ZHLJKW objects.
As an alternate design strategy, the responsibility of creating and maintaining
different singleton )O\ZHLJKW objects can be moved out of the )O\ZHLJKW to
a designated )O\ZHLJKW)DFWRU\. The )O\ZHLJKW can be designed as an inner
class of the )O\ZHLJKW)DFWRU\ class. Since the )O\ZHLJKW class is defined
with a private constructor, external objects are prevented from creating its instances
by directly invoking the constructor. But the )O\ZHLJKW)DFWRU\ can invoke
the )O\ZHLJKW class private constructor to create necessary )O\ZHLJKW objects.
This is because an outer class can access the private methods of its inner class.
In the new design (Figure 17.2), both the data structure (OVW)O\ZHLJKW
+DVK0DS) and the behavior (JHW)O\ZHLJKW method) related to the creation
and maintenance of singleton )O\ZHLJKW objects are moved from the )O\
ZHLJKW class to the )O\ZHLJKW)DFWRU\class. The )O\ZHLJKW instances are
used solely to represent an object’s intrinsic state.
Whenever a client needs to create an instance of a given flyweight type, it
invokes, the JHW)O\ZHLJKW method on the singleton )O\ZHLJKW)DFWRU\
instance, passing the required flyweight type as an argument. The singleton
)O\ZHLJKW)DFWRU\ object maintains the list of existing )O\ZHLJKW objects in
the OVW)O\ZHLJKW instance variable.
-$SingleInstance
FlyweightFactory
lstFlyweight:HashMap
factory:FlyweightFactory
synchronized getFlyweight(flyweightType)
:Flyweight
getInstance():FlyweightFactory
Flyweight
intrinsic_var_1
...
intrinsic_var_n
-Flyweight()
䡲 Create an object with the exclusive extrinsic data and associate the )O\
ZHLJKW object with it. This approach still results in the creation of a large
number of objects but the design becomes more efficient as the intrinsic
data is not duplicated in every object. Instead, it is kept inside a single
shared )O\ZHLJKW object (Design Approach I in the following example).
䡲 Send the extrinsic data as part of a method call to the )O\ZHLJKW object.
This approach results in the creation of few objects with no duplication
(Design Approach II in the following example).
EXAMPLE
To demonstrate the use of the Flyweight pattern, let us design an application that
prints out the data for visiting cards of all the employees of a large organization
with four major divisional offices. A typical visiting card can be assumed to have
the following layout:
䡲 The name and the title are unique for every employee and can be
considered as the extrinsic data.
䡲 The company name remains the same for all employees and every
employee working under a divisional office is given the same divisional
office address. Therefore the company name and division address part of
a visiting card can be treated as the intrinsic data.
VCard
name:String
title:String
company:String
address:String
city:String
state:String
zip:String
print()
DESIGN APPROACH I
In this approach, the extrinsic data is represented as an object and configured
with a )O\ZHLJKW object representing its intrinsic data.
Applying the Flyweight pattern, all the intrinsic data can be moved out of the
9&DUG class into a separate )O\ZHLJKW class. Let us define an interface )O\
ZHLJKW,QWU to be implemented by the )O\ZHLJKW class representing the
visiting card intrinsic data.
(continued)
-$SingleInstance
FlyweightFactory
lstFlyweight:HashMap
factory:FlyweightFactory
synchronized getFlyweight(division:String)
:FlyweightIntr
getInstance():FlyweightFactory
Flyweight
company:String
address:String
city:String
<<interface>> state:String
FlyweightIntr zip:String
getCompany():String getCompany():String
getAddress():String getAddress():String
getCity():String getCity():String
getState():String getState():String
getZip():String getZip():String
After the intrinsic data is removed, the extrinsic data still remains within the
9&DUG class (Listing 17.2). As part of its constructor, the 9&DUG accepts a
)O\ZHLJKW instance representing its intrinsic data. The SULQW method displays
extrinsic data from the 9&DUG and intrinsic data from the associated )O\ZHLJKW
object.
With these objects in place, in order to print the visiting card data, a client
object such as )O\ZHLJKW7HVW (Listing 17.3):
Listing 17.2 9&DUG Class Using a )O\ZHLJKW Object to Represent the Intrinsic Data
DESIGN APPROACH II
Extrinsic data passed to the flyweight as part of a method call and was not
represented as an object (Listing 17.4).
This design approach requires the following two changes to the application
design discussed in Design Approach I.
to
-$SingleInstance
FlyweightFactory
<<Interface>>
FlyweightIntr
lstFlyweight:HashMap
factory:FlyweightFactory
getCompany():String
getAddress():String
getFlyweight(division:String) getCity():String
:FlyweightIntr getState():String
getInstance():FlyweightFactory getZip():String
VCard
<<creates>>
objFW:FlyweightIntr Flyweight
getCompany():String
<<creates>> getAddress():String
getCity():String
FlyweightTest getState():String
getZip():String
flyweight:FlyweightIntr
getInstance()
getFlyweight(division:String)
create()
print()
䡲 9&DUG class:
– Since the extrinsic data is to be passed to the )O\ZHLJKW object and
hence the 9&DUG class is no longer needed, this class can be removed
from the design.
䡲 Once the requested )O\ZHLJKW object is received, the client invokes the
print method on the )O\ZHLJKW object by passing the extrinsic data
(employee name and title).
PRACTICE QUESTIONS
1. Let us consider an online job site that receives XML data files from different
employers with current openings in their organizations. When the number
of vacancies is small, employers can enter details online. When the number
-$SingleInstance
FlyweightFactory Flyweight
lstFlyweight:HashMap getCompany():String
factory:FlyweightFactory getAddress():String
getCity():String
getState():String
getFlyweight(division:String)
getZip():String
:FlyweightIntr
print(name:String,
getInstance():FlyweightFactory
title:String)
<<Interface>>
FlyweightIntr
getCompany():String
FlyweightTest getAddress():String
<<uses>> getCity():String
flyweight:FlyweightIntr getState():String
getZip():String
print(name:String,
title:String)
getInstance()
getFlyweight(division:String)
create()
print(name:String, title:String)
In general, details from (c) through (j) are all considered to be the same
for all jobs posted by a given employer. Apply the Flyweight pattern to
design the process of parsing the input XML file and creating different
-RE objects.
2. A computer user in a typical organization is associated with a user account.
A user account can be part of one or more groups. Permissions on different
resources (such as servers, printers, etc.) are defined at the group level.
Users get all the permissions defined for all groups that their accounts are
part of. Let us consider an organization with three different user groups —
$GPLQLVWUDWRUV, )LHOG2IILFHUV and 6DOHV5HSV. Further assume
that the organization is in the process of migrating user accounts from one
server to a different server environment. As part of this process, all user
accounts are first exported to an XML file as follows.
8VHUV!
8VHU!
8VHU1DPH!3.XFKDQD8VHU1DPH!
3DVVZRUG!3.XFKDQD3DVVZRUG!
*URXS!)LHOG2IILFHUV*URXS!
3HUPLVVLRQV!
3HUPLVVLRQ!3HUP3HUPLVVLRQ!
3HUPLVVLRQ!3HUP3HUPLVVLRQ!
3HUPLVVLRQV!
8VHU!
8VHU!
8VHU1DPH!9.XFKDQD8VHU1DPH!
3DVVZRUG!9.XFKDQD3DVVZRUG!
*URXS!6DOHV5HSV*URXS!
3HUPLVVLRQV!
3HUPLVVLRQ!3HUP3HUPLVVLRQ!
3HUPLVVLRQ!3HUP3HUPLVVLRQ!
3HUPLVVLRQV!
8VHU!
«
«
8VHUV!
It is to be noted that permissions for all accounts in a given group are the
same. This can be considered as the intrinsic data. The user name and the
password details vary from user to user and should be treated as extrinsic
data.
User accounts in the new server environment are created using the
exported XML file. Make any necessary assumptions and design an appli-
cation using the Flyweight pattern to parse the XML file to create different
user account objects.