享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式,享元模式是池技术的重要实现方式。

场景

  • 系统中存在大量的相似对象
  • 细粒度的对象都具有相似的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份
  • 需要缓冲池的场景

实现

源码来自: 菜鸟教程-设计模式

创建抽象接口以及实体类

Shape.java

  1. public interface Shape {
  2. void draw();
  3. }

Circle.java

  1. public class Circle implements Shape {
  2. private String color;
  3. private int x;
  4. private int y;
  5. private int radius;
  6. public Circle(String color){
  7. this.color = color;
  8. }
  9. public void setX(int x) {
  10. this.x = x;
  11. }
  12. public void setY(int y) {
  13. this.y = y;
  14. }
  15. public void setRadius(int radius) {
  16. this.radius = radius;
  17. }
  18. @Override
  19. public void draw() {
  20. System.out.println("Circle: Draw() [Color : " + color
  21. +", x : " + x +", y :" + y +", radius :" + radius);
  22. }
  23. }

创建一个工厂,生成基于给定信息的实体类的对象,重用对象
  1. public class ShapeFactory {
  2. private static final HashMap<String, Shape> circleMap = new HashMap<>();
  3. public static Shape getCircle(String color) {
  4. Circle circle = (Circle)circleMap.get(color);
  5. if(circle == null) {
  6. circle = new Circle(color);
  7. circleMap.put(color, circle);
  8. System.out.println("Creating circle of color : " + color);
  9. }
  10. return circle;
  11. }
  12. }

使用示例
  1. public class FlyweightPatternDemo {
  2. private static final String colors[] =
  3. { "Red", "Green", "Blue", "White", "Black" };
  4. public static void main(String[] args) {
  5. for(int i=0; i < 20; ++i) {
  6. Circle circle =
  7. (Circle)ShapeFactory.getCircle(getRandomColor());
  8. circle.setX(getRandomX());
  9. circle.setY(getRandomY());
  10. circle.setRadius(100);
  11. circle.draw();
  12. }
  13. }
  14. private static String getRandomColor() {
  15. return colors[(int)(Math.random()*colors.length)];
  16. }
  17. private static int getRandomX() {
  18. return (int)(Math.random()*100 );
  19. }
  20. private static int getRandomY() {
  21. return (int)(Math.random()*100);
  22. }
  23. }

在这个例子中,Color 作为内部状态是不变的,其他属性作为可变的外部状态。

优点

  • 减少应用程序创建的对象,降低程序内存占用,增强程序性能

缺点

  • 使系统变得复杂,为了共享内存,需要将一些状态外部化
  • 外部化状态固有固化特性,不应该随着内部系统的变化为改变,否则会导致系统的逻辑混乱

Android 中的应用

  • Message对象的创建,Message.obtain()

参考

书籍:《设计模式之禅》、《Android源码设计模式》
技术文章:菜鸟教程-设计模式