Today we will look into Flyweight design pattern.

今天,我们将探讨Flyweight设计模式。

轻量化设计模式 (Flyweight Design Pattern)

According to GoF, flyweight design pattern intent is:

根据GoF, flyweight设计模式的意图是:

Use sharing to support large numbers of fine-grained objects efficiently

使用共享有效支持大量细粒度对象

Flyweight design pattern is a Structural design pattern like Facade pattern, Adapter Pattern and Decorator pattern.

Flyweight设计模式是一种结构设计模式,例如Facade模式 , Adapter模式和Decorator模式 。

Flyweight design pattern is used when we need to create a lot of Objects of a class. Since every object consumes memory space that can be crucial for low memory devices, such as mobile devices or embedded systems, flyweight design pattern can be applied to reduce the load on memory by sharing objects.

当我们需要创建一个类的许多对象时,可以使用Flyweight设计模式。 由于每个对象都会占用对于低内存设备(例如移动设备或嵌入式系统)至关重要的内存空间,因此可以应用轻量级设计模式来通过共享对象来减少内存负载。

Before we apply flyweight design pattern, we need to consider following factors:

在应用flyweight设计模式之前,我们需要考虑以下因素:

  • The number of Objects to be created by application should be huge.
    应用程序要创建的对象数量应该很大。
  • The object creation is heavy on memory and it can be time consuming too.
    对象的创建占用大量内存,并且也很耗时。
  • The object properties can be divided into intrinsic and extrinsic properties, extrinsic properties of an Object should be defined by the client program.
    对象属性可以分为内部属性和外部属性,对象的外部属性应由客户端程序定义。

To apply flyweight pattern, we need to divide Object property into intrinsic and extrinsic properties. Intrinsic properties make the Object unique whereas extrinsic properties are set by client code and used to perform different operations. For example, an Object Circle can have extrinsic properties such as color and width.

要应用flyweight模式,我们需要将Object属性分为内部属性和外部属性。 内部属性使对象唯一,而外部属性由客户端代码设置并用于执行不同的操作。 例如,对象圆可以具有外部属性,例如颜色和宽度。

For applying flyweight pattern, we need to create a Flyweight factory that returns the shared objects. For our example, lets say we need to create a drawing with lines and Ovals. So we will have an interface Shape and its concrete implementations as Line and Oval. Oval class will have intrinsic property to determine whether to fill the Oval with given color or not whereas Line will not have any intrinsic property.

为了应用flyweight模式,我们需要创建一个Flyweight工厂来返回共享对象。 对于我们的示例,假设我们需要使用线条和椭圆形创建图形。 因此,我们将有一个Shape界面及其具体实现,如LineOval 。 椭圆类将具有固有属性,以确定是否用给定的颜色填充椭圆,而Line将不具有任何固有属性。

Flyweight设计模式界面和具体类 (Flyweight Design Pattern Interface and Concrete Classes)

Shape.java

Shape.java

package com.journaldev.design.flyweight;import java.awt.Color;
import java.awt.Graphics;public interface Shape {public void draw(Graphics g, int x, int y, int width, int height,Color color);
}

Line.java

Line.java

package com.journaldev.design.flyweight;import java.awt.Color;
import java.awt.Graphics;public class Line implements Shape {public Line(){System.out.println("Creating Line object");//adding time delaytry {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic void draw(Graphics line, int x1, int y1, int x2, int y2,Color color) {line.setColor(color);line.drawLine(x1, y1, x2, y2);}}

Oval.java

Oval.java

package com.journaldev.design.flyweight;import java.awt.Color;
import java.awt.Graphics;public class Oval implements Shape {//intrinsic propertyprivate boolean fill;public Oval(boolean f){this.fill=f;System.out.println("Creating Oval object with fill="+f);//adding time delaytry {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic void draw(Graphics circle, int x, int y, int width, int height,Color color) {circle.setColor(color);circle.drawOval(x, y, width, height);if(fill){circle.fillOval(x, y, width, height);}}}

Notice that I have intensionally introduced delay in creating the Object of concrete classes to make the point that flyweight pattern can be used for Objects that takes a lot of time while instantiated.

注意,我在创建具体类的对象时故意引入了延迟,以使flyweight模式可用于实例化时花费大量时间的对象。

轻量化工厂 (Flyweight Factory)

The flyweight factory will be used by client programs to instantiate the Object, so we need to keep a map of Objects in the factory that should not be accessible by client application.

客户端程序将使用flyweight工厂实例化对象,因此我们需要在工厂中保留一个对象映射,客户端应用程序不应访问该映射。

Whenever client program makes a call to get an instance of Object, it should be returned from the HashMap, if not found then create a new Object and put in the Map and then return it. We need to make sure that all the intrinsic properties are considered while creating the Object.

每当客户端程序调用以获取Object的实例时,都应从HashMap返回它,如果找不到,则创建一个新的Object并放入Map中,然后返回它。 我们需要确保在创建对象时考虑所有固有属性。

Our flyweight factory class looks like below code.

我们的flyweight工厂类看起来像下面的代码。

ShapeFactory.java

ShapeFactory.java

package com.journaldev.design.flyweight;import java.util.HashMap;public class ShapeFactory {private static final HashMap<ShapeType,Shape> shapes = new HashMap<ShapeType,Shape>();public static Shape getShape(ShapeType type) {Shape shapeImpl = shapes.get(type);if (shapeImpl == null) {if (type.equals(ShapeType.OVAL_FILL)) {shapeImpl = new Oval(true);} else if (type.equals(ShapeType.OVAL_NOFILL)) {shapeImpl = new Oval(false);} else if (type.equals(ShapeType.LINE)) {shapeImpl = new Line();}shapes.put(type, shapeImpl);}return shapeImpl;}public static enum ShapeType{OVAL_FILL,OVAL_NOFILL,LINE;}
}

Notice the use of Java Enum for type safety, Java Composition (shapes map) and Factory pattern in getShape method.

请注意,在getShape方法中将Java Enum用于类型安全, Java Composition (形状映射)和Factory模式 。

Flyweight设计模式客户端示例 (Flyweight Design Pattern Client Example)

Below is a sample program that consumes flyweight pattern implementation.

下面是使用flyweight模式实现的示例程序。

DrawingClient.java

DrawingClient.java

package com.journaldev.design.flyweight;import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;import com.journaldev.design.flyweight.ShapeFactory.ShapeType;public class DrawingClient extends JFrame{private static final long serialVersionUID = -1350200437285282550L;private final int WIDTH;private final int HEIGHT;private static final ShapeType shapes[] = { ShapeType.LINE, ShapeType.OVAL_FILL,ShapeType.OVAL_NOFILL };private static final Color colors[] = { Color.RED, Color.GREEN, Color.YELLOW };public DrawingClient(int width, int height){this.WIDTH=width;this.HEIGHT=height;Container contentPane = getContentPane();JButton startButton = new JButton("Draw");final JPanel panel = new JPanel();contentPane.add(panel, BorderLayout.CENTER);contentPane.add(startButton, BorderLayout.SOUTH);setSize(WIDTH, HEIGHT);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);startButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {Graphics g = panel.getGraphics();for (int i = 0; i < 20; ++i) {Shape shape = ShapeFactory.getShape(getRandomShape());shape.draw(g, getRandomX(), getRandomY(), getRandomWidth(),getRandomHeight(), getRandomColor());}}});}private ShapeType getRandomShape() {return shapes[(int) (Math.random() * shapes.length)];}private int getRandomX() {return (int) (Math.random() * WIDTH);}private int getRandomY() {return (int) (Math.random() * HEIGHT);}private int getRandomWidth() {return (int) (Math.random() * (WIDTH / 10));}private int getRandomHeight() {return (int) (Math.random() * (HEIGHT / 10));}private Color getRandomColor() {return colors[(int) (Math.random() * colors.length)];}public static void main(String[] args) {DrawingClient drawing = new DrawingClient(500,600);}
}

I have used random number generation to generate different type of Shapes in our frame.

我已经使用随机数生成在框架中生成不同类型的Shape。

If you run above client program, you will notice the delay in creating first Line Object and Oval objects with fill as true and false. After that the program executes quickly since its using the shared objects.

如果在客户端程序上运行,您会注意到创建第一个Line Object和Oval对象时填充为true和false的延迟。 之后,由于程序使用共享库,因此程序将快速执行。

After clicking “Draw” button multiple times, the frame looks like below image.

多次单击“绘制”按钮后,框架如下图所示。

And you will see following output in command line confirming that Objects are shared.

并且您将在命令行中看到以下输出,确认已共享对象。

Creating Line object
Creating Oval object with fill=true
Creating Oval object with fill=false

Thats all for flyweight pattern, we will look into more design patterns in future posts. If you liked it, please share your thoughts in comments section and share it with others too.

这就是flyweight模式的全部内容,我们将在以后的文章中探讨更多的设计模式。 如果您喜欢它,请在评论部分分享您的想法,并与他人分享。

JDK中的Flyweight设计模式示例 (Flyweight Design Pattern Example in JDK)

All the wrapper classes valueOf() method uses cached objects showing use of Flyweight design pattern. The best example is Java String class String Pool implementation.

所有包装器类的 valueOf()方法都使用缓存的对象,这些对象显示了Flyweight设计模式的使用。 最好的示例是Java String类String Pool实现。

举重设计模式要点 (Flyweight Design Pattern Important Points)

  1. In our example, the client code is not forced to create object using Flyweight factory but we can force that to make sure client code uses flyweight pattern implementation but its a complete design decision for particular application.
    在我们的示例中,没有强制客户端代码使用Flyweight工厂创建对象,但是我们可以强制这样做以确保客户端代码使用Flyweight模式实现,但这是针对特定应用程序的完整设计决策。
  2. Flyweight pattern introduces complexity and if number of shared objects are huge then there is a trade of between memory and time, so we need to use it judiciously based on our requirements.
    Flyweight模式引入了复杂性,如果共享对象的数量巨大,那么内存和时间之间就存在交易关系,因此我们需要根据我们的需求明智地使用它。
  3. Flyweight pattern implementation is not useful when the number of intrinsic properties of Object is huge, making implementation of Factory class complex.
    当Object的固有属性数量巨大时,Flyweight模式实现就没有用,这使得Factory类的实现变得复杂。

That’s all for Flyweight design pattern in java.

这就是Java中Flyweight设计模式的全部内容。

翻译自: https://www.journaldev.com/1562/flyweight-design-pattern-java

Java中的Flyweight设计模式相关推荐

  1. 第80节:Java中的MVC设计模式

    第80节:Java中的MVC设计模式 前言 了解java中的mvc模式.复习以及回顾! 事务,设置自动连接提交关闭. setAutoCommit(false); conn.commit(); conn ...

  2. Java中的策略设计模式

    策略设计模式是一种行为模式,其中我们有多种算法/策略来完成一项任务,所使用的算法/策略留给客户选择. 各种算法选项封装在单独的类中. 在本教程中,我们将学习在Java中实现策略设计模式. UML表示形 ...

  3. Java中的命令设计模式

    在本教程中,我们将学习命令模式,这是一种重要的行为设计模式. 它具有一些重要的应用程序,例如在文本编辑器中实现撤消/重做功能. 在命令设计模式中,有一个命令对象位于发送方和接收方对象之间. 发送者对象 ...

  4. Java中的状态设计模式–示例教程

    状态模式是行为设计模式之一 . 当对象根据其内部状态更改其行为时,将使用状态设计模式. 如果必须根据对象的状态更改其行为,则可以在对象中使用状态变量,并使用if-else条件块根据状态执行不同的操作. ...

  5. Java中的Memento设计模式-示例教程

    记忆模式是行为设计模式之一 . 当我们要保存对象的状态以便以后可以恢复时,可以使用Memento设计模式. 记忆模式用于以这种方式实现该目的,即在对象外部无法访问该对象的已保存状态数据,从而保护了已保 ...

  6. Java中的访问者设计模式–示例教程

    访客模式是行为设计模式之一 . 当我们必须对一组相似类型的对象执行操作时,将使用访问者模式. 借助访问者模式,我们可以将操作逻辑从对象移动到另一个类. 例如,假设有一个购物车,我们可以在其中添加不同类 ...

  7. Java中的策略设计模式-示例教程

    策略模式是行为设计模式之一 . 当我们对一个特定任务有多种算法,并且客户端决定在运行时使用的实际实现时,将使用策略模式. 策略模式也称为策略模式 . 我们定义了多种算法,并让客户端应用程序将算法用作参 ...

  8. Java中的迭代器设计模式–示例教程

    迭代器模式是一种行为模式,用于提供遍历一组对象的标准方式. Iterator模式在Java Collection Framework中得到了广泛使用,其中Iterator接口提供了遍历集合的方法. 根 ...

  9. Java中的生成器设计模式

    Java 中的 Builder设计模式是一种创建模式,即用于创建对象,类似于 工厂方法设计模式 ,这也是创建设计模式. 在学习任何设计模式之前,我建议先找出特定设计模式要解决的问题. 众所周知, 必要 ...

最新文章

  1. 【字节流处理】linux下uint8转float的注意事项
  2. TP-GAN 侧脸修复
  3. ASP.NET Core 在 Swagger UI 中显示自定义的 Header Token
  4. 客户端读写数据到HDFS的流程
  5. 力扣151. 翻转字符串里的单词
  6. 东方文学网新进作品【2】
  7. node将图片转换成html文件,node+puppeteer将整个网页html转换为图片并保存【滚动截屏】...
  8. 腾讯视频怎么上传自己的视频?
  9. Shopee2022届校园招聘提前批笔试
  10. Xshell使用方法
  11. Linux:struct dirent
  12. TOM企业邮箱,为你打造企业专属邮箱
  13. c4d如何把文字贴在物体表面_C4D立体贴地面字基础知识点
  14. 回炉STM32入新坑cubemx
  15. 计算机常用英语1600,中考英语必备1600个词汇PDF.pdf
  16. 最新,最严谨的手机号校验
  17. Python+Vue计算机毕业设计牙无忧6ayy4(源码+程序+LW+部署)
  18. 请求一次服务器会显示请求了两次,在Appengin中,每个请求都会到达服务器两次...
  19. 2019年电赛D题《简易电路特性测试仪》全过程
  20. 【Qt】Qt 官方下载网址

热门文章

  1. 读jQuery源码 jQuery.data
  2. windows平台下在Cygwin中运行Nutch1。2的抓取命令提示JAVA_HOME not set解决方案
  3. 语音信号处理基础(二)
  4. [转载] Python字符串函数
  5. [转载] 使用Python处理Excel文件
  6. [转载] 【学习Python】Python查看帮助---help函数
  7. [转载] HTML所有标签及其属性汇总
  8. wpf的控件style
  9. Copy_on_write的简单实现
  10. Linux虚拟机添加新硬盘的全程图解