享元(Flyweight)模式的核心思想就是:如果一个对象创建后就不会改变,那么就没必要重复创建,直接将原来创建的返回就行了,这样既可以节省内存,也可以减少创建对象的过程,提供运行速度

    享元模式在java的标准库中也有应用,比如Byte,Integer是不变类,因此反复创建同一个值的包装类是没有必要的,如果通过Integer.valueOf()这个静态工厂创建的实例,当传入的值是在-128至+127之间时,会直接返回Integer的实例

    在实际使用过程中,享元模式主要应用于缓存,即客户端重复请求某些对象,不必每次创建,而是直接返回内存中缓存的数据,其本质就是缓存共享对象,降低内存消耗

    优点:相同的对象只存储一份,降低系统内对象的数量
    缺点:为了使对象可以共享,需要将一些不能共享的状态外部化,增加了程序的复杂性

    示例:
    现在有个神奇的积木盒,里面有方形和圆形积木,现在有几个孩子过来从盒子里面取积木玩。

    1. public class FlyweightDemo {
    2. public static void main(String[] args) {
    3. Box box = new Box();
    4. box.get(new Square()); // 创建了一个新积木呀: 方形积木
    5. box.get(new Square()); // 方形积木
    6. box.get(new Circle()); //创建了一个新积木呀: 圆形积木
    7. }
    8. // 神奇的积木盒子
    9. static class Box{
    10. private final Map<String,ToyBrick> cache = new HashMap<>();
    11. // 获取想要的积木
    12. public void get(ToyBrick toyBrick){
    13. // 先从缓存取
    14. ToyBrick toyBrickName = cache.get(toyBrick.getName());
    15. // 不存在,则创建
    16. if (toyBrickName == null){
    17. // 创建
    18. toyBrick = toyBrick.create();
    19. System.out.println("创建了一个新积木呀: "+toyBrick.getName());
    20. // 加入缓存
    21. cache.put(toyBrick.getName(),toyBrick);
    22. }else {
    23. // 缓存有,则返回
    24. System.out.println(toyBrickName.getName());
    25. }
    26. }
    27. }
    28. // 抽象积木
    29. interface ToyBrick{
    30. ToyBrick create();
    31. String getName();
    32. }
    33. static class Square implements ToyBrick{
    34. @Override
    35. public Square create() {
    36. return new Square();
    37. }
    38. @Override
    39. public String getName() {
    40. return "方形积木";
    41. }
    42. }
    43. static class Circle implements ToyBrick{
    44. @Override
    45. public Circle create() {
    46. return new Circle();
    47. }
    48. @Override
    49. public String getName() {
    50. return "圆形积木";
    51. }
    52. }
    53. }