23 design patterns (21) java meta-mode and 23 Design Patterns
Dr. Yan Hong's book "JAVA and patterns" describes the Flyweight mode as follows:
In boxing, Flyweight refers to the most lightweight model, that is, "Fly magnitude" or "rainfall level". Here we use the free translation of "Enjoy yuan mode", because it can better reflect the intention of the model. The metadata mode is the object structure mode. The metadata mode supports a large number of fine-grained objects efficiently in a shared manner.
String type in Java
In JAVA, the String type uses the metadata mode. The String object is of the final type and cannot be changed once it is created. In JAVA, string constants exist in the 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 { public static void main(String[] args) { String a = "abc"; String b = "abc"; System.out.println(a==b); }}
In the above example, the result is true, which indicates that both references a and B point to the same String constant "abc" in the constant pool ". This design avoids unnecessary resource consumption when creating N multiple identical objects.
Structure of the metadata Mode
The metadata mode uses a shared object to avoid overhead of a large number of objects with the same content. The most common and intuitive overhead is the memory loss. The key to achieving shared object sharing is differentiation.Internal State)AndExternal State).
An internal state is stored inside the object, and does not change with the environment. Therefore, a shared object can have an internal state and can be shared.
An external State Changes and cannot be shared as the environment changes. The external status of the object must be saved by the client. After the object is created, the object must be uploaded to the object. The external State does not affect the inherent state of the object. They are independent of each other.
The metadata mode can be divided into two forms: simple metadata mode and compound metadata mode.
Simple metadata Mode
In the simple metadata mode, all metadata objects can be shared.
The simple metadata mode involves the following roles:
Abstract Flyweight role:An abstract interface is provided to specify the methods to be implemented for all specific meta-roles.
The specific ConcreteFlyweight role:Implement the interface specified by the abstract metadata role. If there is an inner state, it must provide storage space for the inner state.
FlyweightFactory role:This role is responsible for creating and managing the role. This role must ensure that the object can be shared by the system. When a client object calls a metadata object, the metadata factory role checks whether a metadata object meets the requirements in the system. If you already have a metadata factory role, you should provide the existing metadata object. If the system does not have an appropriate metadata object, the metadata factory role should create a suitable metadata object.
Source code
Abstract meta-role class
Public interface Flyweight {// a schematic method. The parameter state is the external state public void operation (String state );}
In this example, a Character-type intrinsicState attribute represents the specific ConcreteFlyweight class, and its value should be assigned when the object is created. After the object is created, all the internal statuses will not change.
If a metadata object has an external state, all external states must be stored on the client. When a metadata object is used, the client passes in the metadata object. There is only one external state. The parameter state of the operation () method is the external state passed in by the external.
Public class ConcreteFlyweight implements Flyweight {private Character intrinsicState = null;/*** constructor, which uses the Intrinsic state as a parameter to pass in * @ param state */public ConcreteFlyweight (Character state) {this. intrinsicState = state;}/*** the exclusive state is used as a parameter to pass in the method and change the behavior of the method, * but does not change the inherent state of the object. * // @ Override public void operation (String state) {// TODO Auto-generated method stub System. out. println ("Intrinsic State =" + this. intrinsicState); System. out. println ("Extrinsic State =" + state );}}
You must note that the client cannot instantiate a specific metadata class directly. Instead, you must use a factory object to obtain a metadata object using a factory () method. Generally, the metadata factory has only one object in the system. Therefore, you can use the singleton mode.
When the client needs to simply enjoy the metadata object, it needs to call the factory () method of the metadata factory, and pass in the inherent state of the simple metadata object, which is generated by the factory method.
Public class FlyweightFactory {private Map <Character, Flyweight> files = new HashMap <Character, Flyweight> (); public Flyweight factory (Character state) {// first query the object Flyweight fly = files from the cache. get (state); if (fly = null) {// if the object does not exist, create a new Flyweight object fly = new ConcreteFlyweight (state ); // Add the new Flyweight object to the cache files. put (state, fly) ;}return fly ;}}
Client type
public class Client { public static void main(String[] args) { // TODO Auto-generated method stub FlyweightFactory factory = new FlyweightFactory(); Flyweight fly = factory.factory(new Character('a')); fly.operation("First Call"); fly = factory.factory(new Character('b')); fly.operation("Second Call"); fly = factory.factory(new Character('a')); fly.operation("Third Call"); }}
Although the client has applied for three metadata objects, there are only two actually created metadata objects. This is the meaning of sharing. The running result is as follows:
Compound metadata Mode
In the simple meta mode, all the meta objects are just meta objects, that is, they can be directly shared. There is also a complicated situation where some simple elements are combined using the synthesis mode to form a composite object. Such compound object objects cannot be shared, but they can be divided into simple object objects, while the latter can be shared.
The roles involved in the composite meta-role are as follows:
Abstract element (Flyweight) Role: provides an abstract interface to specify the methods to be implemented for all specific element roles.
ConcreteFlyweight: implements the interface specified by the abstract metadata role. If there is an inner state, it must provide storage space for the inner state.
ConcreteCompositeFlyweight: Composite metadata objects cannot be shared. However, a composite metadata object can be decomposed into multiple combinations of simple metadata objects. A composite meta-role is also called a shared meta object.
FlyweightFactory role: this role creates and manages the metadata. This role must ensure that the object can be shared by the system. When a client object calls a metadata object, the metadata factory role checks whether a metadata object meets the requirements in the system. If you already have a metadata factory role, you should provide the existing metadata object. If the system does not have an appropriate metadata object, the metadata factory role should create a suitable metadata object.
Source code
Abstract meta-role class
Public interface Flyweight {// a schematic method. The parameter state is the external state public void operation (String state );}
Specific object color categories
Public class ConcreteFlyweight implements Flyweight {private Character intrinsicState = null;/*** constructor, which uses the Intrinsic state as a parameter to pass in * @ param state */public ConcreteFlyweight (Character state) {this. intrinsicState = state;}/*** the exclusive state is used as a parameter to pass in the method and change the behavior of the method, * but does not change the inherent state of the object. * // @ Override public void operation (String state) {// TODO Auto-generated method stub System. out. println ("Intrinsic State =" + this. intrinsicState); System. out. println ("Extrinsic State =" + state );}}
Composite meta objects are composed of simple meta objects through composite. Therefore, they provide clustering management methods such as add. Because a composite object has different clustering elements, these elements are added after the composite object is created, which means that the state of the composite object will change, therefore, composite object cannot be shared.
The composite metadata role implements the interface specified by the abstract metadata role, that is, the operation () method. This method has a parameter that represents the external state of the composite metadata object. The external States of all elements of a compound object are the same as those of the compound object; the inherent states of a simple object in a compound object are generally not equal, otherwise there will be no use of value.
Public class ConcreteCompositeFlyweight implements Flyweight {private Map <Character, Flyweight> files = new HashMap <Character, Flyweight> (); /*** add a new simple meta object to the aggregation */public void add (Character key, Flyweight fly) {files. put (key, fly);}/*** the external state is passed as a parameter to the Method */@ Override public void operation (String state) {Flyweight fly = null; for (Object o: files. keySet () {fly = files. get (o); fly. operation (state );}}}
The metadata factory role provides two different methods: one is to provide a simple metadata object, and the other is to provide a composite metadata object.
Public class FlyweightFactory {private Map <Character, Flyweight> files = new HashMap <Character, Flyweight> (); /*** composite metadata factory Method */public Flyweight factory (List <Character> compositeState) {condition compositeFly = new condition (); for (Character state: compositeState) {compositeFly. add (state, this. factory (state);} return compositeFly;}/*** simple metadata factory Method */public Flyweight factory (Character state) {// first query the object Flyweight fly = files from the cache. get (state); if (fly = null) {// if the object does not exist, create a new Flyweight object fly = new ConcreteFlyweight (state ); // Add the new Flyweight object to the cache files. put (state, fly) ;}return fly ;}}
Client role
Public class Client {public static void main (String [] args) {List <Character> compositeState = new ArrayList <Character> (); compositeState. add ('A'); compositeState. add ('B'); compositeState. add ('C'); compositeState. add ('A'); compositeState. add ('B'); FlyweightFactory flyFactory = new FlyweightFactory (); Flyweight compositeFly1 = flyFactory. factory (compositeState); Flyweight compositeFly2 = flyFactory. factory (compositeState); compositeFly1.operation ("Composite Call"); System. out. println ("---------------------------------"); System. out. println ("Can shared objects in composite mode:" + (compositeFly1 = compositeFly2); Character state = 'a'; Flyweight fly1 = flyFactory. factory (state); Flyweight fly2 = flyFactory. factory (state); System. out. println ("whether the object can be shared in simple metadata mode:" + (fly1 = fly2 ));}}
The running result is as follows:
From the running results, we can see that the external States of all elements of a compound object are equal to those of the compound object. That is, the outbound operation status is equal to the Composite Call.
From the running results, we can see that the inherent states of a simple object in a compound object are generally not equal. That is, the inner states are B, c, and.
The running result shows that the composite object cannot be shared. That is, the same object compositeState is used to create different objects through the factory.
From the running results, we can see that only metadata objects can be shared. That is, the same object is created two times through the factory using the same object state.
Advantages and disadvantages
The advantage of the Meta mode is that it greatly reduces the number of objects in the memory. However, it also pays a very high price to achieve this:
The metadata mode makes the system more complex. In order for objects to be shared, some States need to be externalized, which complicate the logic of the program.
The metadata mode externalizes the state of the object, and reads the external State to slightly extend the running time.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.