In the flyweight mode, the original intent is the "lightweight" mode.It is used to solve the situation where a large number of identical objects are instantiated multiple times, resulting in a large amount of memory usage.. Sometimes we need to use the public instance method in a class multiple times. Our common practice is to first create an instance of this class and then call this method of this class, after the call is completed, this class becomes junk. If this call method appears frequently, it will pay a lot for object generation and memory usage. The enjoy mode saves as many times as possible for object generation, share multiple objects in a cache. In the aspect mode, the key is to understand the concepts of "internal state" and "external State. Internal status: stored inside the object to be shared by many objects without changing the environment. External state: Generally, it is specified by the client and passed in to the internal object. It changes with the environment.
Example: 1. QQ friend Manager:Manage and display messages sent from each friend. In the process of chatting, communication with a friend only uses one metadata object to send and receive messages, rather than generating a new object for each message sending and receiving. 2. Internet cafe management software:In the Internet cafe management software, the client software sends a request to the server software (for example, raise your hand, release the screen, and deprecate the screen lock ......), the server software also sends commands to the client (for example, remote shutdown, remote monitoring ......), no matter how many interactions occur between the client and the server, each client on the server retains only one object instance. Communication between the server and each client is implemented through this object. Structure:
Abstract flyweight): Specifies the public interface to be implemented for a specific object. Concreteflyweight ):Implement the interface specified by the abstract metadata role. If there is an "inner state", declare the "inner state" as a member variable, so that the object can have a fixed "inner state ". Flyweightfactory ):Creates and manages the shared object. When a client object calls a metadata object, the metadata factory role checks whether a metadata object meets the requirements in the system. If yes, the Yuan factory should provide the existing yuan object. If the system does not have an appropriate yuan object, the Yuan factory role should create a suitable yuan object. Client ):Maintain a reference to all the metadata objects. Provides and manages the "external resource status" of the object ". Schematic code of the structure diagram: // Abstract metadata Abstract class flyweight { // Pass in the external store status Public abstract void operation (string extrinsicstate ); // Display the internal and external statuses Public abstract void show (); } //. Class concreteflyweighta: flyweight { // Inner state variable Private string intrinsicstate = "flyweighta "; // External state variable Private string extrinsicstate; Public override void operation (string extrinsicstate) { This. extrinsicstate = extrinsicstate; } Public override void show () { Console. writeline (this. intrinsicstate + "/t" + this. extrinsicstate ); } } // The specific user B Class concreteflyweightb: flyweight { // Inner state variable Private string intrinsicstate = "flyweightb "; // External state variable Private string extrinsicstate; Public override void operation (string extrinsicstate) { This. extrinsicstate = extrinsicstate; } Public override void show () { Console. writeline (this. intrinsicstate + "/t" + this. extrinsicstate ); } } // Enjoy the Yuan factory and manage the Yuan objects Class flyweightfactory { // Save the object Private hashtable T = new hashtable (); Public flyweightfactory () { T. Add ("A", new concreteflyweighta ()); T. Add ("B", new concreteflyweightb ()); } // Construct or return a metadata object based on the input Intrinsic State, Public flyweight getflyweight (string key) { If (T. containskey (key )) { Return (flyweight) T [Key]; } Return NULL; } } Class class1 {
Public static void main (string [] ARGs) { Flyweightfactory F = new flyweightfactory (); // Here, the meta object A is returned based on the input keyword. Flyweight fw1 = f. getflyweight (""); Fw1.operation ("A's extinsic state "); Fw1.show (); // The metadata object B is returned based on the input keyword B. Flyweight fw2 = f. getflyweight ("B "); Fw2.operation ("B's extinsic state "); Fw2.show (); // Here, the meta object A is returned based on the input keyword. Flyweight fw3 = f. getflyweight (""); Fw3.operation ("Another A's extinsic state "); Fw3.show (); } }
Example of QQ friend Manager: When one of your friends sends messages to QQ, they will beat their profile picture. When you click, they will show their information. Here, "nick name", "message", and "show ()) these attributes and methods are encapsulated into a QQ Show class for managing friends. Therefore, when receiving a message, you need to generate this object, assign values to its message, and then call its show () method. If you keep chatting with a friend, it will keep receiving messages and calling the show () method. If every message is received, such an object will be generated, this will generate many objects. Solve this problem by using the metadata mode: Abstract An abstract metadata, and then make each friend a specific object metadata (friend manager, responsible for communicating messages with the friend ), the internal status is "nickname", the external status is "message", and the common method is "show ()", this ensures that each user creates only one object during the chat process. // Abstract the metadata object and the abstraction of the friend manager. Abstract class qqshow { Private stringNickname; // Internal status, friend nickname Protected stringMessage; // External status, information sent by friends Public qqshow (string nickname) { This. Nickname = nickname; } // Method for receiving information from a friend. Public abstract void receivemessage (string message ); // Simulate the beat display of a friend's profile picture Protected void show () { Console. writeline (nickname + "," + message ); } } // A specific friend Manager Class ggshow: qqshow { Public ggshow (string nickname): Base (nickname ){} // Receives the information sent from the friend and displays the picture beating. Public override void receivemessage (string message) { This. Message = message; Show (); } } // Another specific friend Manager Class mmshow: qqshow { Public mmshow (string nickname): Base (nickname ){} Public override void receivemessage (string message) { This. Message = message; Show (); } } // Enjoy the Yuan factory and manage the Friends Manager Class showfactory { Private hashtable H = new hashtable (); Public qqshowGetqqmember(String nickname) { If (! H. containskey (nickname )) { Switch (nickname) { Case "GG ": H. Add (nickname, new ggshow (nickname )); Break; Case "mm ": H. Add (nickname, new mmshow (nickname )); Break; Default: Break; } } Return (qqshow) H [nickname]; } } Class Client { Public static void main (string [] ARGs) { // Construct the Yuan-sharing Factory Showfactory Sf = new showfactory (); // Construct a GG Object Based on Input keywords Qqshow Q1 = SF.Getqqmember("GG "); // Use the friend manager to receive information sent from GG. Q1.receivemessage ("Hello? "); // Retrieve the friend manager again to receive information sent from gg Qqshow q2 = SF.Getqqmember("GG "); Q2.receivemessage ("what are you doing? "); Qqshow Q3 = SF.Getqqmember("GG "); Q3.receivemessage ("Can I have dinner together tonight? "); Qqshow Q4 = SF.Getqqmember("GG "); Q4.receivemessage ("******************************"); Qqshow Q5 = SF.Getqqmember("GG "); Q5.receivemessage ("I use the same object "); } } Running results
|