JAVA设计模式之蝇量模式

一、蝇量模式简介

Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用。

二、蝇量模式的结构

在这里插入图片描述

三、蝇量模式的角色与职责

  • 抽象享元角色: 所有具体享元类的父类,规定一些需要实现的公共接口。
  • 具体享元角色: 抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。
  • 享元工厂角色: 负责创建和管理享元角色。

四、蝇量模式的具体实现

某游戏在剧情中需要大量的树木装饰,本来他们已经设计了一个模式,但是游戏中加载时间太长,用户体验不好,想让我们帮忙想想办法。
那我们先看看他们是怎么设计的。

1、不使用蝇量模式

方案设计

直接创建1000000个数对象,并使用显示在屏幕上。
在这里通过打印创建时间以及内存使用情况来对比。
在这里插入图片描述

类设计

首先是游戏中的树类,有x坐标、y坐标以及年龄三个域。

// An highlighted block
package design.Flyweight.gys.noFlyweight;
public class Tree {
 private int x;
 private int y;
 private int age;
 public Tree(int x, int y, int age) {
  super();
  this.x = x;
  this.y = y;
  this.age = age;
 }
 public void display() {
 }
}

由于不使用设计模式,需要有参构造器来初始化树对象。而display()方法则不做任何输出。
接着他们使用了一个管理类来管理这1000000个数对象。

// An highlighted block
package design.Flyweight.gys.noFlyweight;
import java.util.ArrayList;
import java.util.Random;
public class Manager {
 ArrayList<Tree> arr=new ArrayList<>();
 Random r=new Random();
 public  void test() { 
  for(int i=0;i<1000000;i++)
   arr.add(new Tree(r.nextInt(), r.nextInt(), r.nextInt()));
  for(Tree t:arr)
   t.display();
 }
}

进入加载游戏的界面。看一下效果

// An highlighted block
package design.Flyweight.gys.noFlyweight;
public class Test {
 public static void main(String[] args) { 
  info();
  new Manager().test();
  info(); 
 } 
 public static void info() {
 long max=Runtime.getRuntime().maxMemory();
 long total=Runtime.getRuntime().totalMemory();
 long free=Runtime.getRuntime().freeMemory();
 long used=total-free;
 System.out.println("最大内存:"+max);
 System.out.println("全部内存:"+total);
 System.out.println("空闲内存:"+free);
 System.out.println("已用内存:"+used);
 System.out.println("时间:"+System.currentTimeMillis());
 System.out.println("-------------");
 }
}

这里的info()方法输出了总的内存、占用内存、空闲内存以及系统的时间:

// An highlighted block
最大内存:259522560
全部内存:16252928
空闲内存:15222784
已用内存:1030144
时间:1545707516538
-------------
最大内存:259522560
全部内存:64888832
空闲内存:34835712
已用内存:30053120
时间:1545707517488
-------------

可以看到,不适用蝇量模式的时候,游戏加载了将近1秒,占用了29M的内存。游戏玩家的视觉体验太差。
下面我们使用蝇量模式来对游戏进行改进。

2、使用蝇量模式

方案设计

在这里插入图片描述

类设计

同样存在一个树类,但是该树拥有的是无参构造器,并且display()方法也不做任何事。

// An highlighted block
package design.Flyweight.gys.Flyweight;
public class Tree {
 private int x;
 private int y;
 private int age;
 public Tree() {
 }
 public void display(int x,int y, int age) { 
 }
}

在上一个管理类中,使用的是LIst容器对树对象进行管理,在蝇量模式中,我们定义三个数组,分别用来存储x坐标、y坐标、年龄:

// An highlighted block
import java.util.Random;
public class Manager {
 private Tree tree=new Tree();
 int[] x=new  int[1000000];
 int[] y=new  int[1000000];
 int[] age=new  int[1000000];
 Random r=new Random();
 public  void test() {
  for(int i=0;i<1000000;i++)
   {
    x[i]=r.nextInt();
    y[i]=r.nextInt();
    age[i]=r.nextInt();
   }
  for(int i=0;i<100000;i++)
   tree.display(x[i],y[i],age[i]);
 }
}

接下来我们测试一下我们的代码加载速度以及运行时间,同样的测试代码:

// An highlighted block
package design.Flyweight.gys.Flyweight;
public class Test {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  info();
  new Manager().test();
  info();
 }
 public static void info() {
  long max=Runtime.getRuntime().maxMemory();
  long total=Runtime.getRuntime().totalMemory();
  long free=Runtime.getRuntime().freeMemory();
  long used=total-free;
  System.out.println("最大内存:"+max);
  System.out.println("全部内存:"+total);
  System.out.println("空闲内存:"+free);
  System.out.println("已用内存:"+used);
  System.out.println("时间:"+System.currentTimeMillis());
  System.out.println("-------------");
 }
}

屏气凝神:

// An highlighted block
最大内存:259522560
全部内存:16252928
空闲内存:15238152
已用内存:1014776
时间:1545708086746
-------------
最大内存:259522560
全部内存:16318464
空闲内存:3642976
已用内存:12675488
时间:1545708087038
-------------

可以看到,加载速度大约在0.25秒左右,内存占用11M。可以说极大的提高了用户体验。
由于本人的电脑比较废,读者可以试着尝试10000000个对象。

五、蝇量模式的优缺点

  1. 优点:
  • 减少运行时的对象实例的个数,节省创建的开销和内存
  • 将对象集中管理
  1. 缺点:
  • 可能会增加系统的设计复杂度
  • 需要专门的管理外部状态
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值