享元模式:
定义:
实例对象的一种缓存思想,程序运行中一些经常用到,内部态不会改变的实例,放入一个缓存池中,重复使用,避免了同样功能的对象,被重复创建,节省资源。不仅是内存资源,连接资源也同样节约
例如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
输出结果可以看到最后两张天猫卡是一个实例