Thoroughly understand the design pattern DesignPattern-flyweight pattern

This article has participated in the "Newcomer Creation Ceremony" activity, and started the road of Nuggets creation together

The principle of flyweight pattern

The Flyweight pattern is defined in "Dahua Design Patterns" as follows: the use of sharing techniques to effectively support a large number of fine-grained objects. Question 1 : What is meant by shared technology? What is a fine-grained object? Sharing technology is a technology that avoids repeatedly generating a large number of similar objects through a shared pool. A fine-grained object refers to an object of a class that implements an interface. A large number of objects are generated during use. There is a large amount of repeated immutable information (type) between objects, and only a small amount of variable information (position). Question 2 : How to support (implement) fine-grained object sharing? In Flyweight mode, the immutable information (such as type) inside the object is called internal state, and a small amount of variable information (such as position) is extracted outside the object, such as the client to determine the variable information. Information is called external state. Therefore, sharing is to put objects into the shared pool according to the internal state, and the client passes in the external state and internal state to obtain the objects in the shared pool. UML class diagram of flyweight pattern:insert image description here

Introduction to the roles of Flyweight Mode:

Flyweight: The abstract class or interface of all concrete flyweight classes. Through this interface, Flyweight can accept and act on the external state. ConcreteFlyweight: inherits the Flyweight abstract class or interface, and adds storage space for the internal state; UnsharedConcreteFlyweight: inherits the Flyweight abstract class or interface, referring to those Flyweight subclasses that do not need to be shared. Because Flyweight interface sharing is possible, but he does not enforce sharing. FlyweightFactory: A flyweight factory, 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 one (if it does not exist) .

Internal state and external state

For example, Go, Gomoku, and Checkers all have a large number of chess objects. Go and Gomoku only have black and white colors, and checkers have more colors, so the color of the chess piece is the internal state of the chess piece; and the difference between the chess pieces is the difference in position. After we make a move, the color of the move is fixed, but the position changes, so the coordinates of the piece are the external state of the piece

  1. The Flyweight pattern imposes two requirements: fine-grained and shared objects. This involves internal state and external state, that is, the information of the object is divided into two parts: internal state and external state
  2. The internal state refers to the information shared by the object, which is stored inside the flyweight object and will not change with the change of the environment.
  3. External state refers to a mark that an object can depend on, and is a non-shareable state that changes as the environment changes.
  4. For example: Go theoretically has 361 vacancies where pieces can be placed, and there may be two or three hundred pieces in each game.

Because of the limited memory space, it is difficult for a server to support more players to play the game of Go. If the flyweight mode is used to process chess pieces, the chess piece object can be reduced to only two instances, which is a good solution. Object overhead.

Features of Flyweight Mode

Avoid creating objects repeatedly and save memory space. Objects are stored in the shared pool according to their internal state, and they can be retrieved from the shared pool when needed.

Flyweight mode usage scenarios

To borrow the words from the design pattern book: if an application uses a large number of objects, and a large number of these objects cause a large storage overhead, it should be considered; there is most of the state of the object can be external state, if deleted The external state of the object, then you can replace many groups of objects with relatively few shared objects, and you can consider using the flyweight pattern.

Flyweight Pattern Notes and Details

  1. In the flyweight mode, "share" means sharing, and "yuan" means object
  2. When there are a large number of objects in the system, these objects consume a lot of memory, and most of the state of the objects can be externalized, we can consider using the flyweight pattern
  3. Judging by the unique identification code, if it exists in memory, return the object identified by the unique identification code, and store it in HashMap/HashTable
  4. Flyweight mode greatly reduces the creation of objects, reduces the occupation of program memory, and improves efficiency
  5. Flyweight mode increases the complexity of the system. It is necessary to separate the internal state and the external state, and the external state has the characteristics of solidification and should not change with the change of the internal state. This is what we need to pay attention to when using the flyweight pattern.
  6. When using the flyweight pattern, pay attention to the division of internal state and external state, and need to have a factory class to control it.
  7. 享元模式经典的应用场景是需要缓冲池的场景,比如 String常量池、 数据库连接池

代码示例

码云地址https://gitee.com/magneto/codeReview/tree/master/DesignPattern/src/pro51/top

享元模式的原理

《大话设计模式》中这样定义享元模式:运用共享技术有效的支持大量细粒度的对象。 问题1:共享技术是指什么?细粒度的对象是什么? 共享技术是一种通过共享池避免重复生成大量的相似对象的技术。 细粒度的对象是指实现一个接口的类的对象,使用过程中会大量产生的对象,对象之间有大量重复的不可变的信息(类型),只有少量可变的信息(位置)。 问题2:如何支持(实现)细粒度的对象共享? 在享元模式中,把对象内部不可变的信息(如类型)称为内部状态,把少量可变的信息(如位置)提取到对象外部,如客户端来决定可变信息,这种可变信息称为外部状态。所以,共享是根据内部状态把对象放入共享池内,客户端传入外部状态和内部状态来获取共享池内的对象。 享元模式的UML类图: insert image description here

享元模式各角色介绍:

Flyweight:所有具体享元类的抽象类或者接口,通过这个接口,Flyweight可以接受并作用于外部状态。 ConcreteFlyweight:继承Flyweight抽象类或者接口,并为内部状态增加存储空间; UnsharedConcreteFlyweight:继承Flyweight抽象类或者接口,指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但他并不强制共享。 FlyweightFactory:一个享元工厂,用来创建并管理Flyweight对象,它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。

内部状态和外部状态

比如围棋、五子棋、跳棋,它们都有大量的棋子对象,围棋和五子棋只有黑白两色,跳棋颜色多一点,所以棋子颜色就是棋子的内部状态;而各个棋子之间的差别就是位置的不同,当我们落子后, 落子颜色是定的,但位置是变化的,所以棋子坐标就是棋子的外部状态

  1. 享元模式提出了两个要求:细粒度和共享对象。这里就涉及到内部状态和外部状态了,即将对象的信息分为两个部分: 内部状态和外部状态
  2. 内部状态指对象共享出来的信息,存储在享元对象内部且不会随环境的改变而改变
  3. 外部状态指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态。
  4. 举个例子:围棋理论上有361个空位可以放棋子,每盘棋都有可能有两三百个棋子对

象产生,因为内存空间有限,一台服务器很难支持更多的玩家玩围棋游戏,如果用享元模式来处理棋子,那么棋子对象就可以减少到只有两个实例,这样就很好的解决了对象的开销问题。

享元模式的特点

避免重复创建对象,节省内存空间。根据内部状态把对象存储在共享池,需要时去共享池取就行。

享元模式使用场景

借用设计模式书中的话就是:如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

享元模式的注意事项和细节

  1. 在享元模式这样理解,“享”就表示共享,“元”表示对象
  2. 系统中有大量对象, 这些对象消耗大量内存, 并且对象的状态大部分可以外部化时,我们就可以考虑选用享元模式
  3. 用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象,用HashMap/HashTable存储
  4. 享元模式大大减少了对象的创建,降低了程序内存的占用,提高效率
  5. 享元模式提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变,这是我们使用享元模式需要注意的地方.
  6. 使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制。
  7. 享元模式经典的应用场景是需要缓冲池的场景,比如 String常量池、 数据库连接池

享元模式的原理

《大话设计模式》中这样定义享元模式:运用共享技术有效的支持大量细粒度的对象。 问题1:共享技术是指什么?细粒度的对象是什么? 共享技术是一种通过共享池避免重复生成大量的相似对象的技术。 细粒度的对象是指实现一个接口的类的对象,使用过程中会大量产生的对象,对象之间有大量重复的不可变的信息(类型),只有少量可变的信息(位置)。 问题2:如何支持(实现)细粒度的对象共享? 在享元模式中,把对象内部不可变的信息(如类型)称为内部状态,把少量可变的信息(如位置)提取到对象外部,如客户端来决定可变信息,这种可变信息称为外部状态。所以,共享是根据内部状态把对象放入共享池内,客户端传入外部状态和内部状态来获取共享池内的对象。 享元模式的UML类图: insert image description here

享元模式各角色介绍:

Flyweight:所有具体享元类的抽象类或者接口,通过这个接口,Flyweight可以接受并作用于外部状态。 ConcreteFlyweight:继承Flyweight抽象类或者接口,并为内部状态增加存储空间; UnsharedConcreteFlyweight:继承Flyweight抽象类或者接口,指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但他并不强制共享。 FlyweightFactory:一个享元工厂,用来创建并管理Flyweight对象,它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。

内部状态和外部状态

比如围棋、五子棋、跳棋,它们都有大量的棋子对象,围棋和五子棋只有黑白两色,跳棋颜色多一点,所以棋子颜色就是棋子的内部状态;而各个棋子之间的差别就是位置的不同,当我们落子后, 落子颜色是定的,但位置是变化的,所以棋子坐标就是棋子的外部状态

  1. 享元模式提出了两个要求:细粒度和共享对象。这里就涉及到内部状态和外部状态了,即将对象的信息分为两个部分: 内部状态和外部状态
  2. 内部状态指对象共享出来的信息,存储在享元对象内部且不会随环境的改变而改变
  3. 外部状态指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态。
  4. 举个例子:围棋理论上有361个空位可以放棋子,每盘棋都有可能有两三百个棋子对

象产生,因为内存空间有限,一台服务器很难支持更多的玩家玩围棋游戏,如果用享元模式来处理棋子,那么棋子对象就可以减少到只有两个实例,这样就很好的解决了对象的开销问题。

享元模式的特点

避免重复创建对象,节省内存空间。根据内部状态把对象存储在共享池,需要时去共享池取就行。

享元模式使用场景

借用设计模式书中的话就是:如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

享元模式的注意事项和细节

  1. 在享元模式这样理解,“享”就表示共享,“元”表示对象
  2. 系统中有大量对象, 这些对象消耗大量内存, 并且对象的状态大部分可以外部化时,我们就可以考虑选用享元模式
  3. 用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象,用HashMap/HashTable存储
  4. 享元模式大大减少了对象的创建,降低了程序内存的占用,提高效率
  5. 享元模式提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变,这是我们使用享元模式需要注意的地方.
  6. 使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制。
  7. 享元模式经典的应用场景是需要缓冲池的场景,比如 String常量池、 数据库连接池

享元模式的原理

《大话设计模式》中这样定义享元模式:运用共享技术有效的支持大量细粒度的对象。 问题1:共享技术是指什么?细粒度的对象是什么? 共享技术是一种通过共享池避免重复生成大量的相似对象的技术。 细粒度的对象是指实现一个接口的类的对象,使用过程中会大量产生的对象,对象之间有大量重复的不可变的信息(类型),只有少量可变的信息(位置)。 问题2:如何支持(实现)细粒度的对象共享? 在享元模式中,把对象内部不可变的信息(如类型)称为内部状态,把少量可变的信息(如位置)提取到对象外部,如客户端来决定可变信息,这种可变信息称为外部状态。所以,共享是根据内部状态把对象放入共享池内,客户端传入外部状态和内部状态来获取共享池内的对象。 享元模式的UML类图: insert image description here

享元模式各角色介绍:

Flyweight:所有具体享元类的抽象类或者接口,通过这个接口,Flyweight可以接受并作用于外部状态。 ConcreteFlyweight:继承Flyweight抽象类或者接口,并为内部状态增加存储空间; UnsharedConcreteFlyweight:继承Flyweight抽象类或者接口,指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但他并不强制共享。 FlyweightFactory:一个享元工厂,用来创建并管理Flyweight对象,它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。

内部状态和外部状态

比如围棋、五子棋、跳棋,它们都有大量的棋子对象,围棋和五子棋只有黑白两色,跳棋颜色多一点,所以棋子颜色就是棋子的内部状态;而各个棋子之间的差别就是位置的不同,当我们落子后, 落子颜色是定的,但位置是变化的,所以棋子坐标就是棋子的外部状态

  1. 享元模式提出了两个要求:细粒度和共享对象。这里就涉及到内部状态和外部状态了,即将对象的信息分为两个部分: 内部状态和外部状态
  2. 内部状态指对象共享出来的信息,存储在享元对象内部且不会随环境的改变而改变
  3. 外部状态指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态。
  4. 举个例子:围棋理论上有361个空位可以放棋子,每盘棋都有可能有两三百个棋子对

象产生,因为内存空间有限,一台服务器很难支持更多的玩家玩围棋游戏,如果用享元模式来处理棋子,那么棋子对象就可以减少到只有两个实例,这样就很好的解决了对象的开销问题。

享元模式的特点

避免重复创建对象,节省内存空间。根据内部状态把对象存储在共享池,需要时去共享池取就行。

享元模式使用场景

借用设计模式书中的话就是:如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

享元模式的注意事项和细节

  1. 在享元模式这样理解,“享”就表示共享,“元”表示对象
  2. 系统中有大量对象, 这些对象消耗大量内存, 并且对象的状态大部分可以外部化时,我们就可以考虑选用享元模式
  3. 用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象,用HashMap/HashTable存储
  4. 享元模式大大减少了对象的创建,降低了程序内存的占用,提高效率
  5. 享元模式提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变,这是我们使用享元模式需要注意的地方.
  6. 使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制。
  7. The classic application scenarios of Flyweight mode are scenarios that require buffer pools, such as String constant pools, database connection pools

Guess you like

Origin juejin.im/post/7088505397639643173