In the book "Java and Patterns" of Dr. Shanhong, this describes the Flyweight pattern:
Flyweight in boxing is the most lightweight, that is, "The fly level" or "rainfall level", where the choice to use the "enjoy meta-mode" of the free translation, because it is more reflective of the intention of the model. The enjoy meta mode is the structure mode of the object. The enjoy meta mode efficiently supports a large number of fine-grained objects in a shared manner.
String types in Java
In the Java language, the string type is the use of the enjoy meta pattern. The string object is the final type, and the object cannot be changed once it is created. In Java, where string constants are present in a constant pool, Java ensures that a string constant has only one copy in the constant pool. String a= "abc", where "abc" is a string constant.
Public class Test { publicstaticvoid main (string[] args) { = "abc"; = "abc"; System.out.println (a= =b);} }
The result in the above example is:true , which means that both A and B two references point to the same string constant "ABC" in the Constant pool. Such a design avoids the unnecessary amount of resource consumption generated when creating n many identical objects.
Structure of the enjoy meta-mode
The enjoy meta mode takes a share to avoid the overhead of having the same content object in large numbers. The most common and intuitive kind of overhead is the loss of memory. The key to sharing the shared meta object is to differentiate between the intrinsic state (the Internal State) and the outer states (External).
An intrinsic state is stored inside the element of the object and does not vary depending on the environment. Therefore, a share can have an intrinsic state and can be shared.
A foreign State is changed with the change of the environment and cannot be shared. The outer state of the object must be saved by the client, and then passed in to the inside of the object when it is needed after the object is created. The outer state can not affect the intrinsic state of the objects, they are independent of each other.
The enjoy meta-mode can be divided into two forms of the simple and complex mode.
Simply enjoy meta mode
In the simple-to-enjoy mode, all the objects of the object can be shared.
The roles involved in the simple-to-enjoy meta-mode are as follows:
abstract enjoy meta (Flyweight) role: An abstract interface is given to specify the methods that are required to be implemented for all of the specific enjoyment meta-roles.
specific concreteFlyweightRole: implements the interface defined by the abstract privileges meta role. If there is an intrinsic state, you must be responsible for providing storage space for the intrinsic state.
enjoy meta-factory (flyweightfactory) role : This role is responsible for creating and managing the rewards role. This role must ensure that the sharing meta-object can be properly shared by the system. When a client object invokes an object, the enjoy Meta factory role checks to see if there is already an eligible object in the system. If it is already available, the meta-factory role should provide the existing one, and if the system does not have an appropriate element of the object, the enjoy meta-factory role should create a suitable object for the privilege.
Source
Abstract enjoy Meta role class
Public Interface Flyweight { // A schematic method, the parameter state is outside the Yun status public void operation (String state);
The concreteflyweight has an intrinsic state, in this case the Intrinsicstate attribute of a character type is represented, and its value should be given when the element object is created. All the intrinsic states are not changed after the object is created.
If an object has an external state, all external states must be stored on the client, and the client is passed in with the object of the privilege when the element is used. There is only one external state, and the operation () method's parameter state is an external incoming foreign.
Public classConcreteflyweightImplementsFlyweight {PrivateCharacter intrinsicstate =NULL; /*** constructor, intrinsic state passed in as parameter *@param State*/ PublicConcreteflyweight (Character state) { This. intrinsicstate =State ; } /*** External state as a parameter in the method, change the behavior of the method, * but does not change the intrinsic state of the object. */@Override Public voidoperation (String state) {//TODO auto-generated Method StubSYSTEM.OUT.PRINTLN ("intrinsic state =" + This. intrinsicstate); System.out.println ("Extrinsic state =" +State ); }}
Enjoy the meta-factory role class, it must be noted that the client cannot instantiate a specific class of classes directly, but must pass a factory object, using a factory () method to get the object of the privilege. In general, there is only one in the entire system for the enjoy Meta factory object, so you can also use singleton mode.
When the client needs to simply enjoy the meta-object, it is necessary to call the factory () method of the Meta factory and pass in the intrinsic state of the desired simple-to-enjoy meta-object, and the factory method produces the desired object.
Public classFlyweightfactory {Privatemap<character,flyweight> files =NewHashmap<character,flyweight>(); PublicFlyweight Factory (Character state) {//find an object from the cache firstFlyweight Fly =Files.get (state); if(Fly = =NULL){ //creates a new flyweight object if the object does not existFly =Newconcreteflyweight (state); //Add this new flyweight object to the cachefiles.put (state, fly); } returnFly; }}
Client class
Public classClient { Public Static voidMain (string[] args) {//TODO auto-generated Method StubFlyweightfactory factory =Newflyweightfactory (); Flyweight Fly= Factory.factory (NewCharacter (' a ')); Fly.operation ("First Call"); Fly= Factory.factory (NewCharacter (' B ')); Fly.operation ("Second Call"); Fly= Factory.factory (NewCharacter (' a ')); Fly.operation ("Third Call"); }}
Although the client has requested three of the objects, only two are actually created, which is the meaning of sharing. The results of the operation are as follows:
Compound enjoy meta mode
In the simple-to-enjoy meta-mode, all the objects of the object are simply to enjoy the meta-object, which means they can be shared directly. There is also a more complex situation, the use of a few simple-to-enjoy composite model to compound, to form a compound to enjoy meta-objects. Such compound-sharing objects cannot be shared by themselves, but they can be decomposed into simple-to-enjoy meta-objects, while the latter can be shared.
The roles involved in the compound-sharing role are as follows:
abstract enjoy meta (Flyweight) role: An abstract interface is given to specify the methods that are required to be implemented for all of the specific enjoyment meta-roles.
specific concreteFlyweightRole: implements the interface defined by the abstract privileges meta role. If there is an intrinsic state, you must be responsible for providing storage space for the intrinsic state.
compound concretecompositeflyweightrole : The object represented by the composite privilege role cannot be shared, However, a composite object can be decomposed into a combination of multiple objects that are simply a single-element object. The compound privilege role is also known as a non-shareable, shared meta object.
enjoy meta-factory (flyweightfactory) role : This role is responsible for creating and managing the rewards role. This role must ensure that the sharing meta-object can be properly shared by the system. When a client object invokes an object, the enjoy Meta factory role checks to see if there is already an eligible object in the system. If it is already available, the meta-factory role should provide the existing one, and if the system does not have an appropriate element of the object, the enjoy meta-factory role should create a suitable object for the privilege.
Source
Abstract enjoy Meta role class
Public Interface Flyweight { // A schematic method, the parameter state is outside the Yun status public void operation (String state);
Specific enjoy meta role classes
Public classConcreteflyweightImplementsFlyweight {PrivateCharacter intrinsicstate =NULL; /*** constructor, intrinsic state passed in as parameter *@param State*/ PublicConcreteflyweight (Character state) { This. intrinsicstate =State ; } /*** External state as a parameter in the method, change the behavior of the method, * but does not change the intrinsic state of the object. */@Override Public voidoperation (String state) {//TODO auto-generated Method StubSYSTEM.OUT.PRINTLN ("intrinsic state =" + This. intrinsicstate); System.out.println ("Extrinsic state =" +State ); }}
A compound-sharing object is composed of a simple-to-enjoy meta-object, so it provides an aggregation management method such as add (). Because a composite object has different aggregation elements, these aggregation elements are added after the compound's object is created, which in itself means that the state of the compound's object is changed, so that the composite object cannot be shared.
The compound-enjoy meta-role implements the interface defined by the abstract-enjoy meta-role, which is the operation () method, which has a parameter that represents the outer state of the composite object. The outer state of all the primitive elements of a compound-sharing object is equal to the outer state of the compound-sharing object, while the intrinsic state of the pure-object contained in a compound-sharing object is generally unequal, otherwise there is no use value.
Public classConcretecompositeflyweightImplementsFlyweight {Privatemap<character,flyweight> files =NewHashmap<character,flyweight>(); /*** Add a new simple-to-enjoy meta-object into the aggregation*/ Public voidAdd (Character key, Flyweight fly) {files.put (key,fly); } /*** The outer state is passed into the method as a parameter*/@Override Public voidoperation (String state) {Flyweight Fly=NULL; for(Object o:files.keyset ()) {Fly=Files.get (o); Fly.operation (state); } }}
The enjoy Meta factory role provides two different methods, one for providing a simple-to-use meta-object, and the other for providing a compound-sharing object.
Public classFlyweightfactory {Privatemap<character,flyweight> files =NewHashmap<character,flyweight>(); /*** Compound to enjoy the meta-factory method*/ PublicFlyweight Factory (list<character>compositestate) {Concretecompositeflyweight Compositefly=Newconcretecompositeflyweight (); for(Character state:compositestate) {Compositefly.add (state, This. Factory (state)); } returnCompositefly; } /*** Simple to enjoy the meta-factory method*/ PublicFlyweight Factory (Character state) {//find an object from the cache firstFlyweight Fly =Files.get (state); if(Fly = =NULL){ //creates a new flyweight object if the object does not existFly =Newconcreteflyweight (state); //Add this new flyweight object to the cachefiles.put (state, fly); } returnFly; }}
Client role
Public classClient { Public Static voidMain (string[] args) {List<Character> compositestate =NewArraylist<character>(); Compositestate.add (A); Compositestate.add (' B '); Compositestate.add (C); Compositestate.add (A); Compositestate.add (' B '); Flyweightfactory flyfactory=Newflyweightfactory (); Flyweight compositeFly1=flyfactory.factory (compositestate); Flyweight CompositeFly2=flyfactory.factory (compositestate); Compositefly1.operation ("Composite Call"); System.out.println ("---------------------------------"); System.out.println (Whether the composite enjoy meta mode can share objects: "+ (compositeFly1 = =compositeFly2)); Character State= ' A '; Flyweight fly1=flyfactory.factory (state); Flyweight Fly2=flyfactory.factory (state); System.out.println ("Pure meta mode can share objects:" + (fly1 = =fly2)); }}
The results of the operation are as follows:
From the running result, it can be seen that the outer state of all the elements of the pure element object of a compound-object is equal to the outer state of the compound-sharing object. The Sinotrans status equals composite call.
From the running results, it can be seen that the intrinsic state of the simple-to-enjoy meta-objects contained in a compound-sharing object is generally unequal. That is, the intrinsic states are B, C, a respectively.
As you can see from the running results, the compound-sharing object cannot be shared. Objects that were created two times by factory, even with the same object compositestate , are not the same object.
From the running results, it can be seen that the simple-to-enjoy meta-objects can be shared. objects created with the same object state through the factory two times are the same object.
Pros and cons of the enjoy meta model
The advantage of the enjoy meta-mode is that it drastically reduces the number of objects in memory. However, the cost of doing this is also high:
The enjoy meta-mode makes the system more complex. In order for objects to be shared, some States need to be externally instantiated, which complicates the logic of the program.
The enjoy meta-mode takes the state of the Meta object out of the way, while reading the external state makes the run time slightly longer.
Java design mode of the sharing meta-mode