结构设计模式 - Flyweight设计模式(享元设计模式)

 

结构设计模式 - Flyweight设计模式

 

今天我们将研究Flyweight 设计模式,Flyweight设计模式又被称为 享元设计模式 。

 

 

目录[ 隐藏 ]

  • 1 Flyweight设计模式
    • 1.1 Flyweight设计模式界面和混凝土类
    • 1.2 轻量级工厂
    • 1.3 Flyweight设计模式客户端示例
    • 1.4 JDK中的Flyweight设计模式示例
    • 1.5 Flyweight设计模式重点

 

Flyweight设计模式

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

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

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

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

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

  • 应用程序要创建的对象数量应该很大。
  • 对象创建在内存上很重要,也可能很耗时。
  • 对象属性可以分为内在属性和外在属性,对象的外在属性应该由客户端程序定义。

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

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

 

Flyweight设计模式界面和混凝土类

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


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 delay
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	@Override
	public 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


package com.journaldev.design.flyweight;

import java.awt.Color;
import java.awt.Graphics;

public class Oval implements Shape {
	
	//intrinsic property
	private boolean fill;
	
	public Oval(boolean f){
		this.fill=f;
		System.out.println("Creating Oval object with fill="+f);
		//adding time delay
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	@Override
	public 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);
		}
	}

}

请注意,我有意在创建具体类的Object时引入了延迟,以表明flyweight模式可以用于实例化时需要花费大量时间的对象。

 

Flyweight工厂

客户端程序将使用flyweight工厂来实例化Object,因此我们需要在工厂中保留一个客户端应用程序无法访问的Objects映射。

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

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

ShapeFactory.java


package com.journaldev.design.flyweight;

import java.util.HashMap;

public class ShapeFactory {

	private static final HashMap shapes = new HashMap();

	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;
	}
}

注意使用Java枚举用于类型安全,Java 组合物(形状地图)和 工厂模式 在 getShape方法。

 

Flyweight设计模式客户端示例

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

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);
	}
}

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

如果您运行在客户端程序之上,您将注意到创建第一个Line对象和Oval对象的延迟,其中fill为true和false。之后,程序自使用共享对象以来快速执行。

多次单击“绘图”按钮后,框架看起来像下面的图像。

结构设计模式 - Flyweight设计模式(享元设计模式)_第1张图片

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


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

这就是所有的flyweight模式,我们将在未来的帖子中研究更多的设计模式。如果您喜欢它,请在评论部分分享您的想法并与其他人分享。

 

JDK中的Flyweight设计模式示例

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

 

Flyweight设计模式重点

  1. 在我们的示例中,客户端代码不会强制使用Flyweight工厂创建对象,但我们可以强制这样做以确保客户端代码使用flyweight模式实现,但它是针对特定应用程序的完整设计决策。
  2. Flyweight模式引入了复杂性,如果共享对象的数量巨大,那么存储器和时间之间存在交易,因此我们需要根据我们的要求明智地使用它。
  3. 当Object的内在属性数量很大时,Flyweight模式实现没有用,这使得Factory类的实现变得复杂。

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

 

转载来源:https://www.journaldev.com/1562/flyweight-design-pattern-java

你可能感兴趣的:(Unix&Unix-Like,设计模式,结构设计模式,设计模式)