2021-07-29

享元模式(学习笔记)

  1. 意图

  运用共享技术有效的支持大量细粒度的对象

  2. 动机

   假设开发了一款简单的游戏:玩家们在地图上移动并进行相互射击。大量的子弹、导弹和爆炸弹片在整个地图上穿行,为玩家提供紧张刺激的游戏体验。但是,运行了几分钟后,游戏因为内存容量不足而发生了崩溃。研究发现,每个粒子(一颗子弹、 一枚导弹或一块弹片)都由包含完整数据的独立对象来表示。当玩家在游戏中鏖战进入高潮后的某一时刻,游戏将无法在剩余内存中载入新建粒子,于是程序就崩溃了

  

  仔细观察粒子Particle类,会注意到颜色(color)和精灵图(sprite)这两个成员变量所消耗的内存要比其他变量多得多。另外,对所有例子来说,这两个成员变量所存储的数据几乎完全一样 (比如所有子弹的颜色和精灵图都一样)。每个粒子的另一些状态 (坐标、 移动矢量和速度)则是不同的,因为这些成员变量的数值会不断变化。内在状态存储于flyweight中,它包含了独立于场景的信息,这些信息使得flyweight可以被共享。而外部状态取决于flyweight场景,并根据场景而变化,因此不可共享。用户对象负责在必要的时候将外部状态传递给Flyweight

    

  3. 适用性

  • 程序需要生成巨大的相似对象,以至于消耗目标对象的所有内存
  • 对象中包含可抽取且能在多个对象间共享的重复状态

  4. 结构

 

  5. 效果

  使用FlyWeight模式时,传输、查找和/或计算外部状态都会产生运行时开销,尤其当flyweight原先被存储为内部状态时。然而,空间上的节省抵消了这些开销。共享的flyweight越多,空间节省越大

  存储节约由以下因素决定:

  1. 由于共享带来的实例总数减少的数量

  2. 对象内部状态的平均数量

  3. 外部状态是计算的还是存储的

  共享的flyweight越多,存储节约的也就越多。节约量随着共享状态的增多而增大。当对象使用大量的内部及外部状态,并且外部状态是计算出来的而非存储的时候,节约量将达到最大

  6. 代码实现  

  如果渲染一片森林 (1,000,000 棵树)!每棵树都由包含一些状态的对象来表示 (坐标和纹理等)。 尽管程序能够完成其主要工作,但很显然它需要消耗大量内存。因为,太多树对象包含重复数据 (名称、 纹理和颜色)。因此我们可用享元模式来将这些数值存储在单独的享元对象中 (Tree­Type类)。现在我们不再将相同数据存储在数千个 Tree对象中,而是使用一组特殊的数值来引用其中一个享元对象。客户端代码不会知道任何事情, 因为重用享元对象的复杂机制隐藏在了享元工厂中

  trees/Tree.java: 包含每棵树的独特状态

package flyweight.trees;import java.awt.*;/** * @author GaoMing * @date 2021/7/19 - 22:14 */public class Tree { private int x; private int y; private TreeType type; public Tree(int x, int y, TreeType type) {  this.x = x;  this.y = y;  this.type = type; } public void draw(Graphics g) {  type.draw(g, x, y); }}

  trees/TreeType.java: 包含多棵树共享的状态

package flyweight.trees;import java.awt.*;/** * @author GaoMing * @date 2021/7/19 - 22:14 */public class TreeType { private String name; private Color color; private String otherTreeData; public TreeType(String name, Color color, String otherTreeData) {  this.name = name;  this.color = color;  this.otherTreeData = otherTreeData; } public void draw(Graphics g, int x, int y) {  g.setColor(Color.BLACK);  g.fillRect(x - 1, y, 3, 5);  g.setColor(color);  g.fillOval(x - 5, y - 10, 10, 10); }}

  trees/TreeFactory.java: 封装创建享元的复杂机制

package flyweight.trees;import java.awt.*;import java.util.HashMap;import java.util.Map;/** * @author GaoMing * @date 2021/7/19 - 22:15 */public class TreeFactory { static Map<String, TreeType> treeTypes = new HashMap<>(); public static TreeType getTreeType(String name, Color color, String otherTreeData) {  TreeType result = treeTypes.get(name);  if (result == null) {   result = new TreeType(name, color, otherTreeData);   treeTypes.put(name, result);  }  return result; }}

  forest/Forest.java: 我们绘制的森林

package flyweight.forest;import flyweight.trees.TreeFactory;import flyweight.trees.TreeType;import flyweight.trees.Tree;import javax.swing.*;import java.awt.*;import java.util.ArrayList;/** * @author GaoMing * @date 2021/7/19 - 22:16 */public class Forest extends JFrame { private List<Tree> trees = new ArrayList<>(); public void plantTree(int x, int y, String name, Color color, String otherTreeData) {  TreeType type = TreeFactory.getTreeType(name, color, otherTreeData);  Tree tree = new Tree(x, y, type);  trees.add(tree); } @Override public void paint(Graphics graphics) {  for (Tree tree : trees) {   tree.draw(graphics);  } }}

  Demo.java: 客户端代码

package flyweight;import java.awt.*;import flyweight.forest.Forest;/** * @author GaoMing * @date 2021/7/19 - 22:17 */public class Demo { static int CANVAS_SIZE = 500; static int TREES_TO_DRAW = 1000000; static int TREE_TYPES = 2; public static void main(String[] args) {  Forest forest = new Forest();  for (int i = 0; i < Math.floor(TREES_TO_DRAW / TREE_TYPES); i++) {   forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE),     "Summer Oak", Color.GREEN, "Oak texture stub");   forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE),     "Autumn Oak", Color.ORANGE, "Autumn Oak texture stub......

原文转载:http://www.shaoqun.com/a/892288.html

跨境电商:https://www.ikjzd.com/

FEN:https://www.ikjzd.com/w/2668

photobucket:https://www.ikjzd.com/w/132

auction:https://www.ikjzd.com/w/2311


1.意图  运用共享技术有效的支持大量细粒度的对象  2.动机  假设开发了一款简单的游戏:玩家们在地图上移动并进行相互射击。大量的子弹、导弹和爆炸弹片在整个地图上穿行,为玩家提供紧张刺激的游戏体验。但是,运行了几分钟后,游戏因为内存容量不足而发生了崩溃。研究发现,每个粒子(一颗子弹、一枚导弹或一块弹片)都由包含完整数据的独立对象来表示。当玩家在游戏中鏖战进入高潮后的某一时刻,游戏将无法在剩余内存
tm商标:https://www.ikjzd.com/w/1069
四川西南一带迎新轮强降雨 成都广元等地有暴雨:http://www.30bags.com/a/425276.html
四川乡村旅游春天绚丽绽放 :http://www.30bags.com/a/409518.html
四川乡村旅游连连看 :http://www.30bags.com/a/409522.html
四川香格里拉与云南香格里拉之比较 :http://www.30bags.com/a/408178.html
四个人同时玩我下面 男人放进女人阳道图片:http://lady.shaoqun.com/a/247075.html
老师让我揉她胸摸下边 撩开裙子摸摸下面流水:http://lady.shaoqun.com/a/248253.html
男人和女人一边摸一边脱 边摸边吃奶边做下面:http://www.30bags.com/m/a/249874.html
深圳宝安科技馆8月展览汇总(持续更新):http://www.30bags.com/a/517601.html
2021时尚深圳展蝶讯馆展览好看吗:http://www.30bags.com/a/517602.html
2021时尚深圳蝶讯馆观展攻略:http://www.30bags.com/a/517603.html
深圳欢乐谷夏浪音乐节有朱星杰吗:http://www.30bags.com/a/517604.html

No comments:

Post a Comment