你还不懂设计模式?- 享元设计模式

享元模式(Flyweight Pattern),顾名思义。享是共享的意思。元是元数据。在Java程序设计中。主要用于减少创建对象的数量,以减少内存占用和提高性能。这种设计模式类似与缓存的设计。在Java中的String字符串缓存池。数据库连接池,线程池也都是是基于这种思想。

为了更加容易理解,还是来举个简单的栗子。

场景①: 当你画画时需要彩笔。彩笔存放在彩笔盒子里面。当我要用中颜色的彩笔时就去盒子里面拿,如果没有的话我就去买一支。用完之后继续放在彩盒子里面。下次要用还是去盒子里面去拿。

分析:
彩笔就是享元模式中的元数据。盒子就是存放元数据的一个块额外空间。买一支新的彩笔相当于创建一个新的对象。如果盒子里面已经有我们想要的彩笔,就不需要再重新去买了,这样就能重复利用这一支笔。

源码实现:

① 先创建一个彩笔接口。

public interface IColourPen {
     
    /**
     * 画画
     * @param content 要画的类容
     */
    void draw(String content);
}

② 创建一个生产彩笔的工厂。如果彩笔盒子里面有就直接取,没有就去买一支。

public class ColourPenFactory{
     
    /**
     * 缓存。相当于彩笔盒子
     */
    private final static Map<ColourPenType, IColourPen> PEN_CACHE = new ConcurrentHashMap<>(8);


    public static IColourPen get(ColourPenType colourPenType){
     
        IColourPen pen = PEN_CACHE.get(colourPenType);
        if (null == pen){
     
            System.out.println(String.format("彩笔盒子没有颜色为%s的彩笔",colourPenType.name()));
            switch (colourPenType.name()){
     
                case "RED":
                    pen = new RedColourPen();
                    System.out.println("去商定给您买了一支新的红色彩笔");
                    break;
                case "BLACK":
                    pen = new BlackColourPen();
                    System.out.println("去商定给您买了一支新的黑色彩笔");
                    break;
                default:
                    throw new IllegalArgumentException("参数错误");
            }
            PEN_CACHE.put(colourPenType,pen);
        }else {
     
            System.out.println(String.format("彩笔盒子中已经存在%s的彩笔啦,直接从盒子里面取给你",colourPenType.name()));
        }
        return pen;
    }



    public enum ColourPenType {
     
        RED, BLACK, GREEN, GRAY, BLUE,
    }
}

③ 测试一下:

IColourPen pen1 = ColourPenFactory.get(ColourPenFactory.ColourPenType.RED);
IColourPen pen2 = ColourPenFactory.get(ColourPenFactory.ColourPenType.RED);
IColourPen pen3 = ColourPenFactory.get(ColourPenFactory.ColourPenType.RED);
System.out.println(pen1);
System.out.println(pen2);
System.out.println(pen3);

IColourPen pen4 = ColourPenFactory.get(ColourPenFactory.ColourPenType.BLACK);
System.out.println(pen4);

输出结果:

彩笔盒子没有颜色为RED的彩笔
去商定给您买了一支新的红色彩笔
彩笔盒子中已经存在RED的彩笔啦,直接从盒子里面取给你
彩笔盒子中已经存在RED的彩笔啦,直接从盒子里面取给你
com.dong.designs.bridge.RedColourPen@24d46ca6
com.dong.designs.bridge.RedColourPen@24d46ca6
com.dong.designs.bridge.RedColourPen@24d46ca6
彩笔盒子没有颜色为BLACK的彩笔
去商定给您买了一支新的黑色彩笔
com.dong.designs.bridge.BlackColourPen@372f7a8d

如上所示。就实现了资源的重复利用,节约了内存空间和cpu性能消耗。并且提高了运行效率。

可以发现享元模式跟单例模式非常相似。但是又不完全是。比如在String缓存池中。对于String类是用很多个不同的String实例的(以上样例不是从这个点去实现的享元模式。但是设计思想是一样的)。而单例模式要求一个类全局范围内必须只能存在一个实例。

你可能感兴趣的:(设计模式,设计模式,java)