享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式 享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
享元模式所涉及到的角色如下:
(1) 抽象享元(Flyweight)角色 :给出一个抽象接口,以规定出所有具体享元角色需要实现的方法。
(2) 具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定出的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。
(3) 享元工厂(FlyweightFactory)角色 :本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
1、创建一个接口
public interface Shape { void draw () ; }
2、创建实现接口的实体类
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 () { System.out.println("Circle: Draw() [Color : " + color + ", x : " + x + ", y :" + y + ", radius :" + radius); } }
3、创建一个工厂,生成基于给定信息的实体类的对象
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; } }
4、享元模式的使用
public class FlyweightPatternMain { 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 ); } }
享元模式的优缺点 :
优点:系统有大量相似对象;需要缓冲池的场景。 缺点:注意划分外部状态和内部状态,否则可能会引起线程安全问题,这些类必须有一个工厂对象加以控制。
本文实现源码 :https://github.com/wshunli/design-patterns/tree/master/src/ch13
参考资料 1、《JAVA与模式》之享元模式 - java_my_life - 博客园https://www.cnblogs.com/java-my-life/archive/2012/04/26/2468499.html 2、设计模式读书笔记—-享元模式 - chenssy - 博客园https://www.cnblogs.com/chenssy/p/3330555.html 3、享元模式 | 菜鸟教程http://www.runoob.com/design-pattern/flyweight-pattern.html 4、JAVA设计模式-享元模式(Flyweight) - 简书https://www.jianshu.com/p/f88b903a166a