Design Patterns - Example of Flyweight Pattern in Java - Go Software

Scenes

Flyweight mode

Introduction

When a software system generates too many objects during operation, it will lead to high operating costs and bring about problems such as system performance degradation.

For example, there are many repeated characters in a text string. If each character is represented by a separate object, it will take up

More memory space, so how do we avoid a large number of identical or similar objects in the system without affecting the client program.

Manipulate these objects in an object-oriented manner?

Flyweight mode is born to solve this kind of problems. Flyweight pattern realizes the reuse of the same or similar objects through sharing technology,

Logically, each character that appears has an object corresponding to it, but physically they share the same flyweight object,

This object can appear in different places of a string, and the same character object points to the same instance. In flyweight mode,

The place where these shared instance objects are stored is called the Flyweight Pool. We can create a flyweight object for each different character,

Put it in the flyweight pool, and take it out from the flyweight pool when needed.

The Flyweight mode efficiently supports the reuse of a large number of fine-grained objects in a shared manner. The key to sharing Flyweight objects is to distinguish the internal

State (Intrinsic State) and external state (Extrinsic State).

The following will briefly introduce the internal state and external state of Flyweight:

(1) The internal state is stored inside the flyweight object and will not change with the environment. The internal state can be shared. Such as the content of the character,

It will not change with the change of the external environment, no matter in any environment, the character "a" is always "a" and will not become "b".

(2) The external state is a state that changes with the environment and cannot be shared. The external state of the flyweight object is usually saved by the client,

And after the flyweight object is created, it is passed into the flyweight object when it needs to be used. One external state versus another external state

are independent of each other. For example, the color of characters can have different colors in different places, for example, some "a" is red,

There are "a"s that are green and so are the size of the characters, there are "a"s that are size five and there are "a"s that are size four. And the color and size of the characters

Small is two independent external states, they can change independently without affecting each other, the client can use the external state

Inject into flyweight object.

Because of the distinction between internal state and external state, we can store objects with the same internal state in the flyweight pool, and the flyweight pool

Objects can be shared, and objects can be taken out of the enjoyment pool when needed to realize reuse of objects. via the fetched pair

Like injecting different external states, you can get a series of similar objects, and these objects actually only store one copy in memory.

Flyweight pattern structure diagram

 

Flyweight role

Flyweight (abstract flyweight class):

It is usually an interface or an abstract class. The public methods of the specific flyweight class are declared in the abstract flyweight class. These methods can provide the internal data (internal state) of the flyweight object to the outside world.

At the same time, external data (external state) can also be set through these methods.

ConcreteFlyweight (specific flyweight class):

It implements the abstract flyweight class, and its instances are called flyweight objects; in the concrete flyweight class, storage space is provided for the internal state. Usually we can combine the singleton mode to design specific flyweight classes,

Provide a unique flyweight object for each specific flyweight class.

UnsharedConcreteFlyweight (non-shared specific flyweight class):

Not all subclasses of the abstract flyweight class need to be shared, and subclasses that cannot be shared can be designed as non-shared concrete flyweight classes;

When an object of a non-shared concrete flyweight class is needed, it can be created directly by instantiation.

FlyweightFactory (flyweight factory class):

The Flyweight Factory class is used to create and manage Flyweight objects. It is programmed for the abstract Flyweight class and stores various types of specific Flyweight objects in a Flyweight pool.

The enjoyment pool is generally designed as a collection of "key-value pairs" (or other types of collections), which can be designed in combination with the factory pattern;

When the user requests a specific flyweight object, the flyweight factory provides a created instance stored in the flyweight pool or creates a new instance (if it does not exist),

Return the newly created instance and store it in the flyweight pool.

The Flyweight factory class is introduced in the Flyweight mode. The function of the Flyweight factory class is to provide a Flyweight pool for storing Flyweight objects. When users need objects,

First get it from the flyweight pool. If it does not exist in the flyweight pool, create a new flyweight object and return it to the user, and save the newly added object in the flyweight pool.

Applications

Through the analysis of the Go software, it is found that there are a large number of black and white stones on the Go board. Their shapes and sizes are exactly the same, but they appear in different positions.

If each chess piece is stored in the memory as an independent object, it will cause the Go software to require a large memory space at runtime,

How to reduce running cost and improve system performance is a problem. In order to solve this problem, it is decided to use the Flyweight pattern to design the chess piece objects of the Go software.

IgoChessman acts as an abstract flyweight class, BlackIgoChessman and WhiteIgoChessman act as concrete flyweight classes, and IgoChessmanFactory acts as a flyweight factory class.

Note:

Blog:
Overbearing rogue temperament blog_CSDN Blog-C#, Architecture Road, Blogger in SpringBoot

accomplish

1. Create a new Go subclass as an abstract flyweight class

//围棋棋子类:抽象享元类
abstract class IgoChessman {
    public abstract String getColor();
    public void display(Coordinates coordinates){
        System.out.println("棋子颜色:"+this.getColor()+",棋子位置:"+coordinates.getX()+coordinates.getY());
    }
}

Here the position of the chess piece is used as the external state.

class with coordinates

//坐标类:外部状态类
public class Coordinates {
    private int x;
    private int y;

    public Coordinates(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

2. Create a new black chess piece class as a specific flyweight class

//黑色旗子类:具体享元类
public class BlackIgoChessman extends IgoChessman{

    @Override
    public String getColor() {
        return "黑色";
    }
}

3. Create a new white chess piece class as a specific flyweight class

//白色旗子类:具体享元类
public class WhiteIgoChessman extends IgoChessman{

    @Override
    public String getColor() {
        return "白色";
    }
}

4. Create a new Go piece factory class as the Flyweight factory class, and use the singleton mode for design

//围棋棋子工厂类:享元工厂类,使用单例模式进行设计
public class IgoChessmanFactory {
    private static IgoChessmanFactory instance = new IgoChessmanFactory();
    //使用Hashtable来存储享元对象,充当享元池
    private static Hashtable ht;

    private IgoChessmanFactory(){
        ht = new Hashtable();
        IgoChessman black,white;
        black = new BlackIgoChessman();
        ht.put("b",black);
        white = new WhiteIgoChessman();
        ht.put("w",white);
    }

    //返回享元工程类的唯一实例
    public static IgoChessmanFactory getInstance(){
        return instance;
    }

    //通过key来获取存储在Hashtable中的享元对象
    public static IgoChessman getIgoChessman(String color){
        return (IgoChessman) ht.get(color);
    }
}

5. Example of client call

public class Client {
    public static void main(String[] args) {
        IgoChessman black1,black2,black3,white1,white2;
        IgoChessmanFactory factory;

        //获取享元工厂对象
        factory = IgoChessmanFactory.getInstance();
        //通过享元工厂获取三颗黑子
        black1 = factory.getIgoChessman("b");
        black2 = factory.getIgoChessman("b");
        black3 = factory.getIgoChessman("b");
        System.out.println("判断两颗黑子是否相同:"+(black1 == black2));
        //通过享元工厂获取两颗白子
        white1 = factory.getIgoChessman("w");
        white2 = factory.getIgoChessman("w");
        System.out.println("判断两颗白子是否相同:"+(white1 == white2));
        //显示棋子
        black1.display(new Coordinates(1,1));
        black2.display(new Coordinates(2,1));
        black3.display(new Coordinates(3,2));
        white1.display(new Coordinates(4,3));
        white2.display(new Coordinates(5,2));
    }
}

6. Summary

When there are a large number of identical or similar objects in the system, the Flyweight pattern is a better solution, which realizes similar objects through sharing technology.

Multiplexing of the same or similar fine-grained objects saves memory space and improves system performance. Compared with other structural design patterns,

Flyweight mode is not used too frequently, but as a design mode based on "saving memory and improving performance", it is used in

It has been applied to a certain extent in software development.

The main advantages of Flyweight mode are as follows:

(1) It can greatly reduce the number of objects in the memory, so that only one copy of the same or similar objects is saved in the memory, which can save system resources and improve system performance.

(2) The external state of the Flyweight pattern is relatively independent and will not affect its internal state, so that Flyweight objects can be shared in different environments.

main disadvantage

(1) Flyweight mode makes the system complex and needs to separate the internal state and external state, which complicates the logic of the program.

(2) In order to make the object shareable, the flyweight mode needs to externalize part of the state of the flyweight object, and reading the external state will make the running time longer.

Applicable scene

(1) A system has a large number of identical or similar objects, resulting in a large amount of memory consumption.

(2) Most of the state of the object can be externalized, and these external states can be passed into the object.

(3) When using the Flyweight mode, it is necessary to maintain a Flyweight pool for storing Flyweight objects, which consumes certain system resources.

Therefore, the flyweight pattern should be used only when the flyweight object needs to be reused many times.

Guess you like

Origin blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131808135