享设计网站注册会员能开发票吗_(享设计网站打不开)

Flyweight 是一种结构设计模式,通过在多个对象之间共享状态的公共部分而不是将所有数据保留在每个对象中,您可以将更多对象放入可用的 RAM 量。

想象一下,您开发了一个在线平台,让用户可以命名一颗明星,并且该平台以少量费用为他们提供终身所有权。

这听起来像是一个伟大的商业理念!

该平台运行良好,直到它不是很受欢迎,但现在您开始看到该平台无法处理天空中越来越多的星星。调试时,您发现平台因 RAM 不足而崩溃。

现在,您可以垂直或水平扩展您的系统以支持更多用户,但稍等片刻,就会产生成本。

是否可以改进我们的设计以减少 RAM 使用量?这就是享元设计模式发挥作用的地方。

享元设计模式

您发现诸如大小、颜色、亮度和精灵之类的 Star 类属性会消耗大量内存。实际上更糟糕的是,这些字段在多颗星上存储的数据几乎相同。此外,每颗恒星都有自己的坐标和名称。

一个对象的常量数据称为它的内在状态。它存在于对象内;其他对象只能读取而不能更改。对象状态的其余部分通常会被外部的其他对象更改,称为外部状态。

根据享元模式,您应该停止将外部状态存储在对象内部。您应该将此状态传递给依赖它的特定方法。只有内在状态保留在对象中,允许在多个上下文中重用它。结果,您将需要更少的这些对象,因为它们仅在其内在状态上有所不同,而其变化远少于其外在状态。

Flyweight 模式只不过是一种优化。您必须确保您的程序确实存在由于内存中同时存在大量相似对象而导致的 RAM 消耗问题。

UML 类图

享设计网站注册会员能开发票吗_(享设计网站打不开)

实施步骤

1. 将将成为享元的类的字段分为两部分:

* 内在状态——包含在许多对象中重复的不变数据的字段。

* 外部状态——包含每个对象唯一的上下文数据的字段。

2. 确保表示内在状态的字段在类中是不可变的。它们只能在构造函数中初始化。

3. 检查使用外在状态场的方法。为方法中使用的每个字段引入一个新参数。

4. 您还可以创建一个工厂类来管理享元池。它应该在创建新的享元之前检查是否已经存在享元。一旦工厂投入运营,客户只能通过它请求享元。绕过享元的固有状态,他们应该向工厂描述所需的享元。

5. 对于要调用的享元对象,客户端必须存储或计算外部状态(上下文)的值。

源代码实现

StarType(Flyweight) 类包含可以在多个星之间共享的星对象状态部分。同一个 StarType 对象可以在许多上下文中使用。

package com.learncsdesign;

import java.util.Arrays;

public class StarType {
	private long brightness;
	private String color;
	private long size;
	private byte[] sprite;

	public StarType(long brightness, String color, long size, byte[] sprite) {
		this.brightness = brightness;
		this.color = color;
		this.size = size;
		this.sprite = sprite;
	}

	public void draw(String name, long x, long y) {
		System.out.println(this + " named " + name + " Star drawn on the sky at coordinates(" + x + "," + y + ")");
	}

	@Override
	public String toString() {
		return "StarType [brightness=" + brightness + ", color=" + color + ", size=" + size + ", sprite="
				+ Arrays.toString(sprite) + "]";
	}

}

Star(Context) 类包含外在状态,对全星来说是唯一的,例如 x、y 和 name。 当与 StarType 对象配对时,上下文表示 Star 对象的完整状态。

package com.learncsdesign;

public class Star {
	private long x;
	private long y;
	private String name;
	private StarType starType;

	public Star(long x, long y, String name, long brightness, String color, long size, byte[] sprite) {
		this.x = x;
		this.y = y;
		this.name = name;
		this.starType = StarTypeFactory.getStarType(brightness, color, size, sprite);
	}

	public void draw() {
		starType.draw(name, x, y);
	}

}

StartTypeFactory(享元工厂)类维护一个现有享元池。 客户端不需要直接创建享元。 相反,他们调用工厂并发送所需享元的内在状态位。 它会查看之前创建的享元并返回一个匹配搜索条件的享元,或者如果没有找到则创建一个新享元。

package com.learncsdesign;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class StarTypeFactory {
	private static Map<String, StarType> starHashMap = new HashMap<>();

	public static StarType getStarType(long brightness, String color, long size,  byte[] sprite) {
		String star = getStarStr(brightness, color, size, sprite);
		if (starHashMap.containsKey(star)) {
			System.out.println(">>> " + star + "Already available in cache");
			return starHashMap.get(star);
		}
		System.out.println(star + "Creating new StartType");
		StarType newStarType = new StarType(brightness, color, size, sprite);
		starHashMap.put(newStarType.toString(), newStarType);
		return newStarType;
	}

	private static String getStarStr(long brightness, String color, long size, byte[] sprite) {
		return "StarType [brightness=" + brightness + ", color=" + color + ", size=" + size + ", sprite="
				+ Arrays.toString(sprite) + "]";
	}
}

在 sky(Client) 类中,星星被命名和绘制。

package com.learncsdesign;

import java.util.ArrayList;
import java.util.List;

public class Sky {
	private List<Star> stars;

	public Sky() {
		stars = new ArrayList<>();
	}

	public void nameStar(long x, long y, String name, long brightness, String color, long size, byte[] sprite) {
		stars.add(new Star(x, y, name, brightness, color, size, sprite));
	}

	public void draw() {
		for (Star star : stars) {
			star.draw();
		}
	}

	public static void main(String args[]) {
		Sky sky = new Sky();
		sky.nameStar(10, 0, "ABC", 1110, "HALO", 11230, new byte[10]);
		sky.nameStar(20, 0, "HHHG", 2220, "SILVER", 23232, new byte[10]);
		sky.nameStar(30, 0, "BHUG", 1110, "HALO", 11230, new byte[10]);
		sky.nameStar(40, 0, "JKUIU", 3330, "SILVER", 11230, new byte[10]);
		sky.nameStar(50, 0, "JKHG", 1110, "HALO", 23232, new byte[10]);
		sky.nameStar(60, 0, "HIGH", 2220, "SILVER", 23232, new byte[10]);
		sky.nameStar(70, 0, "HJHJK", 1110, "HALO", 11230, new byte[10]);

		sky.draw();
	}

}
// Output
StarType [brightness=1110, color=HALO, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]Creating new StartTypeStarType [brightness=2220, color=SILVER, size=23232, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]Creating new StartType>>> StarType [brightness=1110, color=HALO, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]Already available in cacheStarType [brightness=3330, color=SILVER, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]Creating new StartTypeStarType [brightness=1110, color=HALO, size=23232, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]Creating new StartType>>> StarType [brightness=2220, color=SILVER, size=23232, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]Already available in cache>>> StarType [brightness=1110, color=HALO, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]Already available in cacheStarType [brightness=1110, color=HALO, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] named ABC Star drawn on the sky at coordinates(10,0)StarType [brightness=2220, color=SILVER, size=23232, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] named HHHG Star drawn on the sky at coordinates(20,0)StarType [brightness=1110, color=HALO, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] named BHUG Star drawn on the sky at coordinates(30,0)StarType [brightness=3330, color=SILVER, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] named JKUIU Star drawn on the sky at coordinates(40,0)StarType [brightness=1110, color=HALO, size=23232, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] named JKHG Star drawn on the sky at coordinates(50,0)StarType [brightness=2220, color=SILVER, size=23232, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] named HIGH Star drawn on the sky at coordinates(60,0)StarType [brightness=1110, color=HALO, size=11230, sprite=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] named HJHJK Star drawn on the sky at coordinates(70,0)

何时应用享元设计模式

仅当您的程序必须支持大量几乎无法放入 RAM 的对象时,才使用享元设计模式。

享元设计模式的优点

如果您的程序有大量类似的对象,则可以节省大量 RAM。

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 sumchina520@foxmail.com 举报,一经查实,本站将立刻删除。
如若转载,请注明出处:https://www.dasum.cn/7459.html