java 设计模式之享元模式

版权声明:原创文章,欢迎转载,注明出处。 https://blog.csdn.net/uncle_gy/article/details/79183007

名称

Flyweight享元模式

概念

内部状态:在享元对象内部不随外界环境改变而改变的共享部分。
外部状态:随着环境的改变而改变,不能够共享的状态就是外部状态。

意图

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

动机

  • 一个应用程序使用了大量的对象
  • 完全由于使用大量的对象,造成很大的存储开销
  • 对象的大部分状态都可以变为外部状态
  • 如果删除对象的外部状态,那么可以使用相对较少的共享对象取代很多组对象
  • 应用程序不依赖于对象标识。由于Flyweight对象可以被共享,对于概念上有明显区别的对象,标识测试将返回真值。

结构

这里写图片描述

参与者

  • Flyweight(抽象享元类)
    - 描述一个接口,通过这个接口flyweight可以接受并且作用于外部状态
  • ConcreteFlyweight(具体享元类)
    - 实现Flyweight接口,并且为内部状态增加存储空间。ConcreteFlyweight对象必须是可以共享的。它所存储的状态必须是内部的,即它必须独立于ConcreteFlyweight对象的场景。
  • UnsharedConcreteFlyweight(非共享具体享元类)
    - 在Flyweight对象的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。
  • FlyweightFactory(享元工厂类)
    - 创建并且管理flyweight对象
    - 确保合理地共享flyweight,当客户请求一个flyweight时,FlyweightFactory对象提供一个已经创建地地实例或者创建一个。
  • Client
    - 维持一个对flywiehgt地引用
    - 计算或者存储一个(或者多个)flyweight的外部状态。

    示例代码

import java.util.HashMap;

interface Shape {//Flyweight(抽象享元类) 
       void draw();
    }

class Circle implements Shape {//ConcreteFlyweight(具体享元类) 
       private String color;
       private int x;
       private int y;
       private int radius;

       public Circle(String color){
          this.color = color;        
       }

       public void setX(int x) {
          this.x = x;
       }

       public void setY(int y) {
          this.y = y;
       }

       public void setRadius(int radius) {
          this.radius = radius;
       }

       @Override
       public void draw() {
          System.out.println("Circle: Draw() [Color : " + color 
             +", x : " + x +", y :" + y +", radius :" + radius);
       }
    }
class ShapeFactory {//FlyweightFactory(享元工厂类) 
       private static final HashMap<String, Shape> circleMap = new HashMap<>();//UnsharedConcreteFlyweight(非共享具体享元类)

       public static Shape getCircle(String color) {
          Circle circle = (Circle)circleMap.get(color);

          if(circle == null) {\\存在则返回,不存在则创建并且返回
             circle = new Circle(color);
             circleMap.put(color, circle);
             System.out.println("Creating circle of color : " + color);
          }
          return circle;
       }
    }
public class Client{
     private static final String colors[] = 
          { "Red", "Green", "Blue", "White", "Black" };
       public static void main(String[] args) {

          for(int i=0; i < 50; ++i) {
             Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor());
             circle.setX(getRandomX());
             circle.setY(getRandomY());
             circle.setRadius(getRandomR());
             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);
       }
       private static int getRandomR() {
              return (int)(Math.random()*100);
           }
}

输出结果

Creating circle of color : Red
Circle: Draw() [Color : Red, x : 36, y :58, radius :51
Creating circle of color : Black
Circle: Draw() [Color : Black, x : 67, y :71, radius :30
Creating circle of color : White
Circle: Draw() [Color : White, x : 57, y :29, radius :92
Circle: Draw() [Color : Black, x : 31, y :26, radius :26
Circle: Draw() [Color : White, x : 96, y :35, radius :56
Circle: Draw() [Color : White, x : 33, y :45, radius :46
Circle: Draw() [Color : Black, x : 55, y :66, radius :25
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 73, y :16, radius :19
Circle: Draw() [Color : Black, x : 94, y :28, radius :43
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 73, y :97, radius :19
Circle: Draw() [Color : White, x : 12, y :34, radius :65
Circle: Draw() [Color : White, x : 65, y :33, radius :84
Circle: Draw() [Color : Black, x : 48, y :4, radius :15
Circle: Draw() [Color : White, x : 54, y :6, radius :11
Circle: Draw() [Color : Green, x : 23, y :10, radius :1
Circle: Draw() [Color : Black, x : 43, y :2, radius :89
Circle: Draw() [Color : Green, x : 2, y :93, radius :4
Circle: Draw() [Color : Blue, x : 51, y :95, radius :96
Circle: Draw() [Color : Black, x : 56, y :17, radius :28
Circle: Draw() [Color : Black, x : 64, y :68, radius :66
Circle: Draw() [Color : Black, x : 32, y :52, radius :89
Circle: Draw() [Color : Green, x : 12, y :37, radius :9
Circle: Draw() [Color : White, x : 69, y :0, radius :70
Circle: Draw() [Color : Blue, x : 42, y :45, radius :39
Circle: Draw() [Color : White, x : 23, y :8, radius :83
Circle: Draw() [Color : White, x : 40, y :25, radius :31
Circle: Draw() [Color : Red, x : 88, y :21, radius :1
Circle: Draw() [Color : Blue, x : 28, y :69, radius :31
Circle: Draw() [Color : Green, x : 21, y :72, radius :55
Circle: Draw() [Color : Black, x : 26, y :49, radius :69
Circle: Draw() [Color : Blue, x : 10, y :31, radius :21
Circle: Draw() [Color : Red, x : 67, y :66, radius :73
Circle: Draw() [Color : Blue, x : 43, y :33, radius :23
Circle: Draw() [Color : Red, x : 94, y :36, radius :66
Circle: Draw() [Color : White, x : 74, y :68, radius :36
Circle: Draw() [Color : Green, x : 90, y :25, radius :90
Circle: Draw() [Color : Green, x : 79, y :13, radius :75
Circle: Draw() [Color : Red, x : 5, y :6, radius :12
Circle: Draw() [Color : Black, x : 59, y :20, radius :83
Circle: Draw() [Color : Red, x : 91, y :94, radius :88
Circle: Draw() [Color : Black, x : 38, y :11, radius :71
Circle: Draw() [Color : Black, x : 63, y :79, radius :87
Circle: Draw() [Color : White, x : 44, y :22, radius :65
Circle: Draw() [Color : Blue, x : 33, y :70, radius :17
Circle: Draw() [Color : Blue, x : 91, y :10, radius :68
Circle: Draw() [Color : Green, x : 92, y :6, radius :93
Circle: Draw() [Color : Blue, x : 92, y :20, radius :33
Circle: Draw() [Color : Black, x : 43, y :22, radius :41
Circle: Draw() [Color : Black, x : 63, y :64, radius :20
Circle: Draw() [Color : Black, x : 4, y :50, radius :32

可以看到只创建了5次对象,其他时候都是已经存在的对象的复用。

猜你喜欢

转载自blog.csdn.net/uncle_gy/article/details/79183007
今日推荐