1、什么是享元模式?
Flyweight模式的目的是使用共享对象有效地支持大量细粒度对象。考虑一个应用程序场景,其中涉及创建大量对象,这些对象仅在几个参数方面是惟一的。换句话说,这些对象包含一些内在的、不变的数据,这些数据在所有对象中都是通用的。需要创建和维护这个内部数据,将其作为正在创建的每个对象的一部分。就内存使用和性能而言,创建和维护大量这样的对象是非常昂贵的。Flyweight模式可用于此类场景,以设计一种更有效的创建对象的方法。下面是Flyweight设计模式的类图
2、场景分析
面向对象编程使编程变得简单和有趣。通过将真实世界的实体建模到编程世界中,它使程序员的工作更容易。程序员创建一个类,并通过创建该类的对象来实例化它。此对象对真实世界实体和应用程序内的对象建模,并彼此协调,以完成所需的工作,太多的对象可能会消耗大量的内存,并且会降低应用程序的运行速度,甚至导致内存不足。Flyweight模式旨在控制这类对象的创建,并为您提供了基本的缓存机制。
3、代码实现
public final class PlatformFactory {
private static Map<String, Platform> map = new HashMap<>();
private PlatformFactory() {
throw new AssertionError("Cannot instantiate the class");
}
public static synchronized Platform getPlatformInstance(String platformType) {
Platform platform = map.get(platformType);
if (platform == null) {
switch (platformType) {
case "C":
platform = new CPlatform();
break;
case "CPP":
platform = new CPPPlatform();
break;
case "JAVA":
platform = new JavaPlatform();
break;
case "RUBY":
platform = new RubyPlatform();
break;
}
map.put(platformType, platform);
}
return platform;
}
}
上面的类包含一个静态映射,它将String对象作为键,将Platform类型对象作为值。我们不想创建这个类的实例,所以保持它的构造函数私有并抛出AssertionError,以避免在类中意外创建对象。
public class TestFlyweight {
public static void main(String[] args) {
Code code = new Code();
code.setCode("C Code...");
Platform platform = PlatformFactory.getPlatformInstance("C");
platform.execute(code);
System.out.println("*************************");
code = new Code();
code.setCode("C Code2...");
platform = PlatformFactory.getPlatformInstance("C");
platform.execute(code);
System.out.println("*************************");
code = new Code();
code.setCode("JAVA Code...");
platform = PlatformFactory.getPlatformInstance("JAVA");
platform.execute(code);
System.out.println("*************************");
code = new Code();
code.setCode("JAVA Code2...");
platform = PlatformFactory.getPlatformInstance("JAVA");
platform.execute(code);
System.out.println("*************************");
code = new Code();
code.setCode("RUBY Code...");
platform = PlatformFactory.getPlatformInstance("RUBY");
platform.execute(code);
System.out.println("*************************");
code = new Code();
code.setCode("RUBY Code2...");
platform = PlatformFactory.getPlatformInstance("RUBY");
platform.execute(code);
}
}
4、何时使用享元模式?
1、应用程序使用大量对象。
2、存储成本高是因为物品的数量太多。
3、大多数对象状态可以是外部的。
4、一旦去除外部状态,许多对象组可能会被相对较少的共享对象替换。
5、应用程序不依赖于对象标识。由于flyweight对象可以共享,所以对于概念上不同的对象,身份测试将返回true。