Yang Juyi's design mode

Posted by jeturman on Mon, 22 Jun 2020 06:09:17 +0200

1, What is the sharing mode
When it comes to sharing element mode, the first thing I think about is pool technology. String constant pool, database connection pool, buffer pool and so on are all applications of sharing element mode, so sharing element mode is an important way to realize pool technology.

For example, every time we create a string object, we need to create a new string object, so the memory overhead will be huge. So if we create the string object "adam" for the first time, and then create the same string "adam" for the next time, we just point its reference to "adam", so that we can realize the sharing of "adam" string in memory.

For example, when playing online chess on the Internet, a server connects multiple clients (players). If we want to create objects for each chess piece, hundreds of objects may be generated for a chess piece. If the players have more than one point, because of the limited memory space, it is difficult for a server to support. Therefore, we need to use the sharing mode to reduce the number of chess pieces to Several examples. The following gives the definition of sharing mode.

Flyweight, which uses sharing technology to effectively support a large number of fine-grained objects. The UML structure diagram is as follows:

Among them, Flyweight is an abstract role. It is the abstract class of product, and defines the interface or implementation of the external state and internal state of the object (see the back for the contents related to the external state and internal state); ConcreteFlyweight is the specific shareware role, which is the specific product class, and implements the business defined by the abstract role; unshared ConcreteFlyweight is the shareable shareware role, which generally does not appear in the shareware factory ; FlyweightFactory is a shareware factory, which is used to construct a pool container and provide methods to get objects from the pool.

1. Flyweight abstract class
Flyweight can accept and act on external states through the superclass or interface of all specific primitive classes.

public abstract class Flyweight {
    //Internal state
    public String intrinsic;
    //External state
    protected final String extrinsic;

    //Require that the sharing role must accept the external state
    public Flyweight(String extrinsic) {
        this.extrinsic = extrinsic;
    }

    //Define business operations
    public abstract void operate(int extrinsic);

    public String getIntrinsic() {
        return intrinsic;
    }

    public void setIntrinsic(String intrinsic) {
        this.intrinsic = intrinsic;
    }
}

2. ConcreteFlyweight class
Inherit Flyweight superclass or implement Flyweight interface, and increase storage space for its internal state.

public class ConcreteFlyweight extends Flyweight {

    //Accept external status
    public ConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    //Logical processing according to external state
    @Override
    public void operate(int extrinsic) {
        System.out.println("specific Flyweight:" + extrinsic);
    }

}

3. UnsharedConcreteFlyweight class
Refers to Flyweight subclasses that do not need to be shared.

public class UnsharedConcreteFlyweight extends Flyweight {

    public UnsharedConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    @Override
    public void operate(int extrinsic) {
        System.out.println("Details not shared Flyweight:" + extrinsic);
    }

}

4. FlyweightFactory class
A sharing factory is used to create and manage Flyweight objects. It is mainly used to ensure reasonable sharing of Flyweight. When a user requests a Flyweight, the FlyweightFactory object provides a created instance or creates an instance.

public class FlyweightFactory {

    //Define a pool container
    private static HashMap<String, Flyweight> pool = new HashMap<>();

    //Xiangyuan factory
    public static Flyweight getFlyweight(String extrinsic) {
        Flyweight flyweight = null;

        if(pool.containsKey(extrinsic)) {    //The object is in the pool
            flyweight = pool.get(extrinsic);
            System.out.print("already existing " + extrinsic + " Take directly from the pool---->");
        } else {
            //Create sharing object according to external state
            flyweight = new ConcreteFlyweight(extrinsic);
            //Put in the pool
            pool.put(extrinsic, flyweight);
            System.out.print("establish " + extrinsic + " And take it out of the pool---->");
        }

        return flyweight;
    }
}

5. Client

public class Client {

    public static void main(String[] args) {
        int extrinsic = 22;

        Flyweight flyweightX = FlyweightFactory.getFlyweight("X");
        flyweightX.operate(++ extrinsic);

        Flyweight flyweightY = FlyweightFactory.getFlyweight("Y");
        flyweightY.operate(++ extrinsic);

        Flyweight flyweightZ = FlyweightFactory.getFlyweight("Z");
        flyweightZ.operate(++ extrinsic);

        Flyweight flyweightReX = FlyweightFactory.getFlyweight("X");
        flyweightReX.operate(++ extrinsic);

        Flyweight unsharedFlyweight = new UnsharedConcreteFlyweight("X");
        unsharedFlyweight.operate(++ extrinsic);
    }

}

The operation results are as follows:

From this result, we can see that when X, Y and Z are created for the first time, they are created first and then taken out of the pool. When X is created for the second time, because the pool already exists, they are taken out of the pool directly. This is the sharing mode.

2, Internal state and external state
The above definition of sharing pattern puts forward two requirements for us: fine-grained and shared objects. We know that allocating too many objects to an application program will damage the performance of the program, and it is also easy to cause memory overflow. To avoid this situation, the sharing technology is used. Here we need to mention the internal state and external state.

Because of the requirement of fine-grained objects, it is inevitable that there will be a large number of objects with similar properties. At this time, we will divide the information of these objects into two parts: internal state and external state.

Internal state refers to the information shared by an object, which is stored in the sharing object and will not change with the change of the environment; external state refers to a mark that an object can depend on, which is a state that changes with the change of the environment and cannot be shared.

Let's take the simplest example. We have played chess and card games. For example, go and checkers have a large number of chess objects. Go and checkers only have black and white colors. Checkers have a little more colors, but they don't change much, so the color of the chess pieces is the internal state of the pieces. The difference between the pieces is the position. We fall Well, the drop color is fixed, but the position is changed, so the azimuth coordinate is the external state of the chess piece.

So why use the sharing mode here? It can be imagined that in the above mentioned chess games, for example, go, there are 361 empty spaces in theory for playing chess. Under normal circumstances, each chess game may have two or three hundred chess objects. Because of the limited memory space, it is difficult for a server to support more players to play go games. If you use the sharing mode to deal with chess, then the number of chess objects can be reduced Until there are only two instances, this can solve the problem of object overhead.

3, The application of enjoy yuan mode
1. When to use
When there are a large number of objects in the system
When these objects consume a lot of memory
When most of the state of these objects can be externalized
2. Method
Judged by unique ID code, if there is one in memory, the object identified by the unique ID code will be returned and stored in HashMap/HashTable
3. Advantages
Greatly reduces the creation of objects, reduces the occupation of program memory, and improves efficiency
4. Disadvantages
The complexity of the system is improved. The internal state and external state need to be separated, and the external state has curing characteristics and should not change with the change of internal state
5. Use scenario
There are a lot of similar objects in the system
Scenarios requiring buffer pools
6. Application examples
String constant pool
Database connection pool
7. Precautions
Pay attention to dividing internal state and external state, otherwise it may cause thread safety problems
These classes must be controlled by a factory class
4, The realization of enjoy element mode
For an application instance, the above template is already a good example. It is similar to a String constant pool. There are no objects in the pool after creation. If there are objects in the pool, they will be taken directly from the pool.

In order to better understand the sharing model, here's another example. For example, I took a small outsourcing project to build a product display website. Later, his friends also wanted to build such a website, but the requirements were different. Of course, we can't directly copy and paste another one. Some hope it's in the form of news release, some hope it's in the form of blog, etc, And because of the cost, we can't rent a space for each website.

In fact, the website structure similarity they need here is very high, and they are not high traffic websites. If they are divided into multiple virtual spaces for processing, it is equivalent to a lot of instance objects of the same website, which is a waste of a lot of resources of the server. If it is integrated into a website to share its relevant codes and data, then server resources such as hard disk, memory, CPU, database space can be shared to reduce server resources; for code, because it is an instance, maintenance and expansion are easier.

Then you can use the sharing mode. The UML diagram is as follows:

  1. Website abstract class
 public abstract class WebSite {
 
     public abstract void use();
     
 }

2. Specific websites

public class ConcreteWebSite extends WebSite {

    private String name = "";

    public ConcreteWebSite(String name) {
        this.name = name;
    }

    @Override
    public void use() {
        System.out.println("Website category:" + name);
    }

}

3. Network Factory
Here, HashMap is used as the pool, and the operations of joining and fetching from the pool are realized through put and get methods.

 public class WebSiteFactory {

    private HashMap<String, ConcreteWebSite> pool = new HashMap<>();

    //Get site categories
    public WebSite getWebSiteCategory(String key) {
        if(!pool.containsKey(key)) {
            pool.put(key, new ConcreteWebSite(key));
        }

        return (WebSite)pool.get(key);
    }

    //Get total site categories
    public int getWebSiteCount() {
        return pool.size();
    }

}

4. Client client
The test case here gives two websites. Originally, we need to do three product presentations and three Blog websites, that is, we need six website instances, but in fact, they are essentially the same code. We can use different user ID numbers to distinguish different users. The specific data and templates can be different, but the code core and database are shared.

public class Client {

    public static void main(String[] args) {
        WebSiteFactory factory = new WebSiteFactory();

        WebSite fx = factory.getWebSiteCategory("Product display");
        fx.use();

        WebSite fy = factory.getWebSiteCategory("Product display");
        fy.use();

        WebSite fz = factory.getWebSiteCategory("Product display");
        fz.use();

        WebSite fa = factory.getWebSiteCategory("Blog");
        fa.use();

        WebSite fb = factory.getWebSiteCategory("Blog");
        fb.use();

        WebSite fc = factory.getWebSiteCategory("Blog");
        fc.use();

        System.out.println("The total number of site classifications is:" + factory.getWebSiteCount());
    }

}

The operation results are as follows:

It can be seen that although we have made six websites, there are only two website classifications. This basically realizes the purpose of sharing objects in the sharing element mode, but think about the internal state and external state mentioned above. In fact, there is no difference between objects, only their sharing part.

5. Users
So we add a user class as the external state of the website class and pass the user object in the use() method. The UML is as follows:

Next, add a User class.

public class User {

    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

Then modify the use() method and add parameters. Take the abstract class as an example: public abstract void use(User user);

In the client, only one user needs to be added to each website, such as: fx.use(new User(“userName”));

The operation results are as follows:

In this way, the internal and external state can be coordinated. Even if the requirements of thousands of websites are the same or similar, the actual development code is also the classification.

Topics: Database network