Introduction to enjoy yuan pattern

“This is the ninth day of my participation in the August More Text Challenge. For details, see: August More Text Challenge.”

The shared element mode mainly shares common objects, reducing memory usage and improving system access efficiency. These shared objects usually consume a lot of memory or need to query a large number of interfaces or use database resources, so they are uniformly extracted and used as shared objects.

In the process of using this mode, you need to use a share factory to manage these independent objects and shared objects to avoid thread safety problems.

Enjoy the idea of the design of the yuan pattern: reduce memory use to improve efficiency, and the previous learning of the prototype pattern by cloning objects to generate complex objects, reduce calls to the remote system.

Enjoy yuan and immutability

When using the enjoy meta schema, the enjoy meta object can be used in different scenarios and its state must be ensured that it cannot be modified. That is, a share object can only be initialized once by its constructor, and it cannot expose its setters or common member variables to other objects.

The flyweight factory

To make it easier to access the various share objects, you can create a factory method to manage the cache pool of existing share objects.

The factory method takes the internal state of the target share object from the client and returns it directly if the target share can be found in the cache pool ahead of time. If it is not found, a enjoy object is automatically created and added to the cache pool.

Enjoy the structure of the meta-pattern

  • The enjoy element pattern is just an optimization that should be used when dealing with memory consumption problems associated with a large number of similar objects occupying memory simultaneously.

  • The enjoy metaclass contains the state of parts of the original object that can be shared across multiple objects.

  • The scenario class contains the different external states in the original object. The scenario and the enjoy element object together can represent the whole state of the original object.

  • The client is responsible for calculating or storing the external state of the share element.

  • The share factory manages the cache pool of existing shares.

With a factory, clients don’t have to create the enjoy directly; they just call the factory and pass it some of the internal state of the target enjoy. The factory will search for the previously created treats according to the parameters. If the treats satisfy the requirements, the factory will return directly, if not, the factory will create a new treat.

Use the enjoy element mode only when the program must support a large number of objects and does not have enough memory capacity.

  • The program needs to produce a large number of similar objects
  • This will use up all the memory on the target device
  • Objects contain duplicate states that can be extracted and shared across multiple objects

implementation

1. Split the class member variables that need to be rewritten as enjoy elements into two parts

  • Internal state: Member variables that contain immutable data that can be reused across many objects
  • External state: Member variables that contain different scenario data for each object

2. Retain member variables that represent the internal state of the class and make their properties unmodifiable. (These invariant variables can only be initialized by the constructor.)

3. Find all methods that use external state member variables, create a new parameter for each member variable in the method, and use that parameter instead of the member variable

4. You can optionally create a factory class to manage the share cache pool, which is responsible for checking existing shares when creating them. If you choose to use a factory, clients can only request the enjoyment through the factory, and they need to pass the intrinsic state of the enjoyment to the factory as a parameter

5. The client must store and calculate the value of the external state in order to call the methods of the enjoy object. External state and member variables that refer to enjoy elements can be moved to separate scenario classes.

Advantage: If your program has many similar objects, you can save a lot of memory.

Disadvantages: Execution speed may be sacrificed for memory, code may become more complex.

Enjoy elements show how a large number of small objects can be generated, and the look and feel pattern shows how an entire subsystem can be represented by a single object.

Demo

/// </summary> public class Flyweight {private Car _sharedState; public Flyweight(Car car) { this._sharedState = car; } public void Operation(Car uniqueState) { string s = JsonConvert.SerializeObject(this._sharedState); string u = JsonConvert.SerializeObject(uniqueState); Console.WriteLine("Flyweight:Displaying shared "+s+" and unque "+u+" state"); }}Copy the code
/// <summary> // <summary> // <summary> // <summary> // <summary> /// </summary> public class FlyweightFactory { private List<Tuple<Flyweight,string>> flyweights=new List<Tuple<Flyweight,string>>(); public FlyweightFactory(params Car[] args) { foreach (var elem in args) { flyweights.Add(new Tuple<Flyweight,string>(new  Flyweight(elem),this.getKey(elem))); } } public string getKey(Car key) { List<string> elements = new List<string>(); elements.Add(key.Model); elements.Add(key.Color); elements.Add(key.Company); if (key.Owner! =null&& key.Number! =null) { elements.Add(key.Number); elements.Add(key.Owner); } elements.Sort(); return string.Join("_",elements); } public Flyweight GetFlyweight(Car sharedState) { string key = this.getKey(sharedState); if (flyweights.Where(t=>t.Item2==key).Count()! =0) {console. WriteLine(" there is no data in the cache in the share factory "); this.flyweights.Add(new Tuple<Flyweight,string>(new Flyweight(sharedState),key)); } else {console. WriteLine(" buffer pool with...") ); } return this.flyweights.Where(t => t.Item2 == key).FirstOrDefault().Item1; } public void listFlyweights() { var count = flyweights.Count; foreach (var item in flyweights) { Console.WriteLine(item.Item2); } } } public class Car { public string Owner { get; set; } public string Number { get; set; } public string Company { get; set; } public string Model { get; set; } public string Color { get; set; }}Copy the code
static void Main(string[] args) { var factory = new FlyweightFactory( new Car { Company = "Chevrolet", Model = "Camaro2018", Color = "pink" }, new Car { Company = "Mercedes Benz", Model = "C300", Color = "black" }, new Car { Company = "Mercedes Benz", Model = "C500", Color = "red" }, new Car { Company = "BMW", Model = "M5", Color = "red" }, new Car { Company = "BMW", Model = "X6", Color = "white" } ); factory.listFlyweights(); addCarToPoliceDatabase(factory, new Car { Number = "CL234IR", Owner = "James Doe", Company = "BMW", Model = "M5", Color = "red" }); addCarToPoliceDatabase(factory, new Car { Number = "CL234IR", Owner = "James Doe", Company = "BMW", Model = "X1", Color = "red" }); factory.listFlyweights(); Console.ReadKey(); } static void addCarToPoliceDatabase(FlyweightFactory Factory, Car Car) {console. WriteLine(" add a new Car"); var flyweight = factory.GetFlyweight(new Car { Color = car.Color, Model = car.Model, Company = car.Company }); flyweight.Operation(car); }Copy the code

For the xiang yuan factory need to pay special attention to, it is to retrieve the total situation of data in the cache pool, found is not to find, then create a new object.

Small remarks

Life is short, I don’t want to pursue what I can’t see, I just want to grasp what I can see.

I am A hui, thank you for reading, if it is helpful to you, please click like, forward thank you.