【结构型模型】享元模式

一、享元模式概述

享元模式定义又叫蝇量模式,运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式。(对象结构型模式)

享元模式的设计一个关键的地方是先要区分内部状态和外部状态

  • 内部状态:存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享(例如:字符的内容)
  • 外部状态:随环境改变而改变的、不可以共享的状态。享元对象的外部状态通常由客户端保存,并在享元对象被创建之后,需要使用的时候再传入到享元对象内部。一个外部状态与另一个外部状态之间是相互独立的(例如:字符的颜色和大小)
  • 享元模式的优缺点
    • 优点
      • 1.减少运行时对象实例的个数,节省内存;
      • 2.将许多"虚拟"对象的状态集中管理。
    • 缺点
      • 为了使对象可以共享,需要将享元对象的部分状态外部化,分离内部状态和外部状态,使程序逻辑复杂。
  • 适用环境
    • 1.一个系统有大量相同或者相似的对象,造成内存的大量耗费;
    • 2.对象的大部分状态都可以外部化,可以将这些外部状态传入对象中;
    • 3.在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,在需要多次重复使用享元对象时才值得使用享元模式。
  • 享元模式和工厂模式、单例模式
    • 在区分出不同种类的外部状态后,创建新对象时需要选择不同种类的共享对象,这时就可以使用工厂模式来提供共享对象,在共享对象的维护上,经常会采用单例模式来提供单实例的共享对象。
  • 享元模式和组合模式
    • 在使用工厂模式来提供共享对象时,比如某些时候共享对象中的某些状态就是对象不需要的,可以引入组合模式来提升自定义共享对象的自由度,对共享对象的组成部分进一步归类、分层,来实现更复杂的多层次对象结构,当然系统也会更难维护。
  • 享元模式和策略模式
    • 策略模式中的策略属于一系列功能单一、细粒度的细粒度对象,可以作为目标对象来考虑引入享元模式进行优化,但是前提是这些策略是会被频繁使用的,如果不经常使用,就没有必要了。

二、代码实现

享元模式主要包含3个角色:

  • **Flyweight(抽象享元类):**通常是接口或抽象类,抽象享元类中声明了具体享元类公共方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)
  • **ConcreteFlyweight(具体享元类):**继承抽象享元类,在具体享元类中为内部状态提供存储空间。通常可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象
  • **FlyweightFactory(享元工厂类):**创建并管理享元对象,将各种具体享元类存储到一个享元池中,享元池一般为"键值对"集合,可以结合工厂模式进行设计。当用户请求一个具体享元对象时,享元池中如果保存的有就直接返回给用户,如果没有就创建该享元对象返回给用户并存储到享元池中。

我们将创建一个 Shape 接口和实现了 Shape 接口的实体类 Circle 。下一步是定义工厂类 ShapeFactory

ShapeFactory 有一个 CircleHashMap ,其中键名为 Circle 对象的颜色。无论何时接收到请求,都会创建一个特定颜色的圆。ShapeFactory 检查它的 HashMap 中的 circle 对象,如果找到 Circle 对象,则返回该对象,否则将创建一个存储在 hashmap 中以备后续使用的新对象,并把该对象返回到客户端。

FlyWeightPatternDemo 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(red / green / blue/ black / white),以便获取它所需对象的颜色。

参考:https://www.runoob.com/design-pattern/flyweight-pattern.html

2.1 抽象享元
java 复制代码
package FlyWeight.draw;
//抽象享元
public interface Shape {
	void draw();
}
2.2 具体享元
java 复制代码
package FlyWeight.draw;

//具体享元
public class Circle implements Shape {
	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() {
		// TODO Auto-generated method stub
		System.out.println("Circle: Draw() [Color : " + color 
		         +", x : " + x +", y :" + y +", radius :" + radius);
	}

}
2.3 享元工厂
java 复制代码
package FlyWeight.draw;
import java.util.HashMap; 

//享元工厂
public class ShapeFactory {
	private static final HashMap<String, Shape> circleMap = new HashMap<>();

	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;
	}
}
2.4 客户端
java 复制代码
package FlyWeight.draw;

public class Test {
	private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" };

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		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);
	}
}
2.5 UML图

三、代码结构图

相关推荐
morning_judger3 天前
【设计模式系列】享元模式(十五)
java·设计模式·享元模式
Mr. zhihao3 天前
享元模式及其运用场景:结合工厂模式和单例模式优化内存使用
单例模式·享元模式
老攀呀3 天前
Flyweight(享元)
享元模式
Mr. zhihao5 天前
享元模式在 JDK 中的应用解析
java·享元模式
wrx繁星点点5 天前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
balong.8 天前
享元模式-实现大颗粒度对象缓存机制
享元模式
无敌岩雀8 天前
C++设计模式结构型模式———享元模式
开发语言·c++·设计模式·享元模式
zzzhpzhpzzz12 天前
设计模式——享元模式
算法·设计模式·享元模式
伯牙碎琴1 个月前
十一、结构型(享元模式)
享元模式
麦克·唐1 个月前
享元模式(C++)
开发语言·c++·享元模式