1.场景问题解决
1.1 场景描述
1.2 OO设计
1.3 需求变动
1.4 带来问题
2.用设计模式改进
2.1 分析
大量的微小的对象,对象属性拆开-内部属性和外部属性拆开;
比如树对象,普通设计为:有一个集合存储树对象,每个对象有其对应的横坐标,纵坐标,及年龄 .
而蝇量模式为: 多个集合(每个集合长度一样),第一个集合保存所有虚拟树对象,第二个保存所有树的横坐标,第三个保存树的所有纵坐标,第四个保存所有树的年龄. 在需要的情况下在将每个集合中的值拿出来组合树对象.
2.2 重新设计
2.3 源码
- oo模式,Tree(树对象),TreesTest(树集合),OOTest(测试类)
public class Tree {
private int xCoord, yCoord, age;
public Tree(int xCoord, int yCoord, int age) {
this.xCoord = xCoord;
this.yCoord = yCoord;
this.age = age;
}
public void display() {
// System.out.print("x");
}
}
public class TreesTest {
private int length = 10000000;
private Tree[] treelst = new Tree[length];
public TreesTest() {
for (int i = 0; i < length; i++) {
treelst[i] = new Tree((int) (Math.random() * length),
(int) (Math.random() * length),
(int) (Math.random() * length) % 5);
}
}
public void display() {
for (int i = 0, len = treelst.length; i < len; i++) {
treelst[i].display();
}
}
}
public class OOTest {
public static void main(String[] args) {
showMemInfo();
TreesTest mTreesTest;
mTreesTest = new TreesTest();
showMemInfo();
mTreesTest.display();
showMemInfo();
}
public static void showMemInfo() {
// 最大内存:
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("");
}
}
- 蝇量模式,TreeFlyWeight(蝇量树),TreeManager(蝇量树管理),FlyWeightTest(测试类)
public class TreeFlyWeight {
public TreeFlyWeight() {
}
public void display(int xCoord, int yCoord, int age) {
// System.out.print("x");
}
}
public class TreeManager {
private int length = 10000000;
int[] xArray = new int[length],
yArray = new int[length],
AgeArray = new int[length];
private TreeFlyWeight mTreeFlyWeight;
public TreeManager() {
mTreeFlyWeight = new TreeFlyWeight();
for (int i = 0; i < length; i++) {
xArray[i] = (int) (Math.random() * length);
yArray[i] = (int) (Math.random() * length);
AgeArray[i] = (int) (Math.random() * length) % 5;
}
}
public void displayTrees() {
for (int i = 0; i < length; i++) {
mTreeFlyWeight.display(xArray[i], yArray[i], AgeArray[i]);
}
}
}
public class FlyWeightTest {
public static void main(String[] args) {
showMemInfo();
TreeManager mTreeManager;
mTreeManager = new TreeManager();
showMemInfo();
mTreeManager.displayTrees();
showMemInfo();
}
public static void showMemInfo() {
// 已分配内存中的剩余空间 :
long free = Runtime.getRuntime().freeMemory();
// 分配内存:
long total = Runtime.getRuntime().totalMemory();
// 最大内存:
long max = Runtime.getRuntime().maxMemory();
// 已占用的内存:
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("");
}
}
- 支持多种植物模式,Plant(植物抽象类),Tree(蝇量树),Grass(蝇量草),PlantFactory(保存植物厂房),PlantManager(植物管理器),FlyWeight2Test(测试类)
public abstract class Plant {
public Plant() {
}
public abstract void display(int xCoord, int yCoord, int age);
}
public class Tree extends Plant {
@Override
public void display(int xCoord, int yCoord, int age) {
// System.out.print("Tree x");
}
}
public class Grass extends Plant {
@Override
public void display(int xCoord, int yCoord, int age) {
// System.out.print("Grass x");
}
}
public class PlantFactory {
private HashMap<Integer, Plant> plantMap = new HashMap<Integer, Plant>();
public PlantFactory() {
}
public Plant getPlant(int type) {
if (!plantMap.containsKey(type)) {
switch (type) {
case 0:
plantMap.put(0, new Tree());
break;
case 1:
plantMap.put(1, new Grass());
break;
}
}
return plantMap.get(type);
}
}
public class PlantManager {
private int length = 10000000;
private int[]
xArray = new int[length],
yArray = new int[length],
AgeArray = new int[length],
typeArray = new int[length];
private PlantFactory mPlantFactory;
public PlantManager() {
mPlantFactory=new PlantFactory();
for (int i = 0; i < length; i++) {
xArray[i] = (int) (Math.random() * length);
yArray[i] = (int) (Math.random() * length);
AgeArray[i] = (int) (Math.random() * length) % 5;
typeArray[i]= (int) (Math.random() * length) % 2;
}
}
public void displayTrees() {
for (int i = 0; i < length; i++) {
mPlantFactory.getPlant(typeArray[i]).display(xArray[i], yArray[i], AgeArray[i]);
}
}
}
public class FlyWeight2Test {
public static void main(String[] args) {
showMemInfo();
PlantManager mPlantManager;
mPlantManager = new PlantManager();
showMemInfo();
mPlantManager.displayTrees();
showMemInfo();
}
public static void showMemInfo() {
// 已分配内存中的剩余空间 :
long free = Runtime.getRuntime().freeMemory();
// 分配内存:
long total = Runtime.getRuntime().totalMemory();
// 最大内存:
long max = Runtime.getRuntime().maxMemory();
// 已占用的内存:
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("");
}
}
3.设计模式总结
3.1 定义
**蝇量模式:**通过共享的方式高效地支持大量细粒度的对象。
3.2 分析思路
3.3 蝇量模式优缺点
- 优点:
-
- 减少运行时的对象实例个数,节省创建开销和内存
-
- 将许多“虚拟”对象的状态集中管理
- 缺点:
-
- 系统设计更加复杂
-
- 需要专门维护对象的外部状态
4. 设计模式使用场景及注意
4.1 适用场合:
- 需要大量细粒度对象
- 这些对象的外部状态不多
- 按照内部状态分成几个组,每一个组都仅用一个蝇量对象代替
5.参考文章
内容总计于HeadFirst设计模式及相关视频