设计模式之享元模式
2021-04-12 本文已影响0人
夜色流冰
FlyWeight模式,也就是享元模式,其主要目的是“尽可能减少内存的使用量,于相似物件中分享尽可能多的信息”!,在面向对象的世界里,我们主要通过对象来打交道,所以需要创建大量的对象。所以对于面向对象的语言来说,主要是通过减少对象创建的数量来减少内存占用,从而提高了性能。
其实核心也就是通过对象的复用技术来避免重复创建符合要求的对象,该模式试图通过检索符合匹配规则的对象,如果有就重用之,没有则创建一个新的对象(同时存储起来,供下次使用)。仔细思考下,
事实上这个模式结合创建者模式使用效果更佳,在创建者创建对象的时候,对于可以复用的对象直接返回就可以了,不需要再次创建!(看下文例子)。
事实上,这个模式使用时很广泛的,比如线程池的使用、Android 的消息处理机制Message对象,其内部使用了next引用形成了链表结构来创建和复用、EventBus的PendingPost 对象其内部使用了head和tail引用也是形成了链表结构在创建和复用PendingPost对象等等。
另外用Design Patterns - Flyweight Pattern文中的例子也能很好的说明这个模式的作用:我们只创建了五个不同颜色的Circle对象,就可以绘制20个或者更多不同位置的圆圈。
注意看上面的UML图,有一个Shape接口,提供了绘制的draw方法;Circle类实现了该接口。同时使用ShapeFactory这个工厂类用来创建Circle对象,该工厂类使用了一个HashMap来存储已经创建的Circle对象。
public interface Shape {
void draw();
}
public class Circle implements Shape {
private String color;//颜色
private int x,y, radius;//圆圈的位置和半径
public Circle(String color){
this.color = color;
}
//省略了set和get方法
@Override
public void draw() {
System.out.println("Circle: Draw() [Color : " + color + ", x : " + x + ", y :" + y + ", radius :" + radius);
}
}
最主要的就是看看ShapeFactory这个对象的实现:
public class ShapeFactory {
private static final HashMap circleMap = new HashMap();
//工厂方法,用来创建颜色为color的Circle对象
public static Shape getCircle(String color) {
//从hashMap中获取color颜色的Circle对象
Circle circle = (Circle)circleMap.get(color);
//这里有个细节,就是在使用的时候在初始化。
if(circle == null) {
circle = new Circle(color);
//将Circle对象存起来
circleMap.put(color, circle);
System.out.println("Creating circle of color : " + color);
}
return circle;
}
}
事实上在这里使用WeakHashMap
也是个不错的选择。
客户端使用代码如下:
public class FlyweightPatternDemo {
private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };
public static void main(String[] args) {
for(int i=0; i < 20; ++i) {
Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();
}
}
private static String getRandomColor() {
return colors[(int)(Math.random()*colors.length)];
}
private static int getRandomX() {
return (int)(Math.random()*100 );
}
private static int getRandomY() {
return (int)(Math.random()*100);
}
}
在Android开发中,性能优化里内存优化是重中之重,可以在相关的场景使用该模式。
参考资料《享元模式维基百科》
《Design Patterns - Flyweight Pattern》