享元模式

享元模式:
定义:
实例对象的一种缓存思想,程序运行中一些经常用到,内部态不会改变的实例,放入一个缓存池中,重复使用,避免了同样功能的对象,被重复创建,节省资源。不仅是内存资源,连接资源也同样节约
例如String的常量池,数据库的连接池,Integer,Long内部使用的都是这种方式。
与注册式的单例区别,注册式的单例是根据对象的类名作为key来存储实例,保证对象唯一,享元模式是根据业务制定key并没有唯一性限制。
享元工厂类通常与单例结合使用,对象缓存池需要单例。
享元模式,会存在线程安全问题,关注内部态,外部态。
内部态,外部态:举例理解
内部态:人,手足口,这些器官都理解为内部态
外部态:苏醒,睡着,为两个外部态。
内部态不会改变,外部态会改变,需要关注外部态,不能让一个睡着的人自己走路。

写法:
定义一个抽象类,提供一个功能方法
定义一个类,实现抽象类,这个类的实例就是享元模式中的元。
定义一个工厂类,工厂类维护一个对象池,对象池使用单例模式,提供一个方法,通过指定的业务key判断对象池是否存在,存在即返回,不存在new一个新对象,返回同时放入对象池(此处类似于注册式单例,但是不是单例,上面已经解释了)

补充知识:
String 类型的字面量会放入一个常量池,即便是拼接的,只要字面值相等jdk会处理放入常量池中,对象为引用传递,新定义一个String对象,会把引用指向常量池中相同的对象,内存地址相同,==便成立

代码:
package com.easybike.bikebos.taskcreate.model.test;

/**

  • 购物刷卡,存在一个卡包,不同场景使用不同的卡
    */
    public interface ShopCard {
    void byByMoney();
    }

package com.easybike.bikebos.taskcreate.model.test;

/**

  • 实现抽象类
    */
    public class Card implements ShopCard{

    private String cardName;

    public Card(String cardName) {
    this.cardName = cardName;
    }

    @Override
    public void byByMoney() {
    System.out.println(“使用:”+cardName);
    }
    }

package com.easybike.bikebos.taskcreate.model.test;

import java.util.HashMap;
import java.util.Map;

public class CardFactory {
/**
* 卡包
*/
private static Map<String,ShopCard> shopCardMap = new HashMap<>();

public CardFactory() {
    shopCardMap.put("京东卡",new Card("京东卡"));
}

public static ShopCard getCardByName(String name){
    if(shopCardMap.containsKey(name)){
        return shopCardMap.get(name);
    }
    Card card =new Card(name);
    shopCardMap.put(name,card);
    return card;
}

}

package com.easybike.bikebos.taskcreate.model.test;

import com.alibaba.fastjson.JSON;

public class test {

public static void main(String[] args) {
    ShopCard card = CardFactory.getCardByName("京东卡");
    card.byByMoney();
    System.out.println(card);
    card = CardFactory.getCardByName("唯品会卡");
    card.byByMoney();
    System.out.println(card);

    card = CardFactory.getCardByName("天猫卡");
    card.byByMoney();
    System.out.println(card);

    card = CardFactory.getCardByName("天猫卡");
    card.byByMoney();
    System.out.println(card);

}

}

com.easybike.bikebos.taskcreate.model.test.test
使用:京东卡
com.easybike.bikebos.taskcreate.model.test.Card@b1a58a3
使用:唯品会卡
com.easybike.bikebos.taskcreate.model.test.Card@6438a396
使用:天猫卡
com.easybike.bikebos.taskcreate.model.test.Card@e2144e4
使用:天猫卡
com.easybike.bikebos.taskcreate.model.test.Card@e2144e4

输出结果可以看到最后两张天猫卡是一个实例

上一篇:类设计技巧


下一篇:Python元组拆包捡到8倍镜快准狠