享元模式
最近和女朋友出去逛街,看到了一个让我心跳加速的事情:共享女友。
可惜我有女朋友了,不然… 你懂得….
看到这一幕让我有点似曾相识的感觉,这不就是设计模式中的享元模式吗?在一个池中,共享对象。
一、享元模式(Flyweight)基本概念
1.1 什么是享元模式
说到享元模式,第一个想到的应该就是池技术了,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。
比如我们每次创建字符串对象时,都需要创建一个新的字符串对象的话,内存开销会很大,所以如果第一次创建了字符串对象”andy”,下次再创建相同的字符串”andy”时,只是把它的引用指向”andy”,这样就实现了”andy”字符串再内存中的共享。
下面给出享元模式的定义:
享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象。
对享元模式的理解:“享” 表示共享 “元” 表示对象。
1.2 类图
1.3 主要角色
(1)Flyweight是抽象享元角色。它是产品的抽象类,同时定义出对象的外部状态和内部状态(外部状态及内部状态相关内容见后方)的接口或实现;
(2)ConcreteFlyweight是具体享元角色,是具体的产品类,实现抽象角色定义的业务;UnsharedConcreteFlyweight是不可共享的享元角色,一般不会出现在享元工厂中;
(3)FlyweightFactory是享元工厂,它用于构造一个池容器,同时提供从池中获得对象的方法。
二、享元模式之共享女友
2.1 分析
(1)对于我们的“女友“,如果是同一个人的话,我们希望之实例化一次;如果不是同一个人的话,那需要重新的实例化。
(2)可以把“女友“放在一个池子里,然后从池子进行获取”女友“,从而达到资源的共享。
2.2 类图
2.3 编码
定义一个女朋友类GirlFriend:
package com.kfit.flyweight.sharegirlfriend;
/**
* 女朋友类 - 封装女朋友的信息
*
* 这里定义一个接口,在享元模式中,并不是必须的。
*
* 在设计模式中,一定不能太死板,好多设计模式都是灵活进行变换的。
*
* @author 悟纤「公众号SpringBoot」
* @date 2020-11-28
* @slogan 大道至简 悟在天成
*/
public class GirlFriend {
private String name;//女朋友的名字;
//其它的信息...
//private String cup;//你懂得...
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
复制代码
定义工厂类:
package com.kfit.flyweight.sharegirlfriend;
import java.util.HashMap;
import java.util.Map;
/**
*
* 专门生产女朋友的...
*
* @author 悟纤「公众号SpringBoot」
* @date 2020-11-28
* @slogan 大道至简 悟在天成
*/
public class GirlFriendFactory {
/**
* 存放对象的容器,共享数据之所以可以共享,就是因为存放在了一个容器里。
*/
private static Map<String,GirlFriend> girlFriendMap = new HashMap<>();
/**
* 这里就是享元模式 - 共享资源 设计的核心了。
*
* 这里我们假设name 是唯一的。
*
* @return
*/
public static GirlFriend getGirlFriend(String name){
/**
* 1、 先从容器中获取,获取到直接返回;
* 2、未获取到需要创建对象,然后放到容器中。
* 注意:这里并没有考虑多线程的安全问题,这里只是为了把享元模式这种设计模式说清楚。
*/
GirlFriend girlFriend = girlFriendMap.get(name);
if(girlFriend == null){
girlFriend = new GirlFriend();
girlFriend.setName(name);
girlFriendMap.put(name,girlFriend);
}
return girlFriend;
}
}
复制代码
测试Me:
/**
* 现实中,女朋友不让我去体验共享女朋友,在代码世界还是我说的算。
*
* @author 悟纤「公众号SpringBoot」
* @date 2020-11-28
* @slogan 大道至简 悟在天成
*/
public class Me {
public static void main(String[] args) {
//第一次获取的时候会进行资源的创建.
GirlFriend girlFriend1 = GirlFriendFactory.getGirlFriend("貂蝉");
GirlFriend girlFriend2 = GirlFriendFactory.getGirlFriend("西施");
//再次获取就会从容器中进行获取,从而达到资源的共享。
GirlFriend girlFriend11 = GirlFriendFactory.getGirlFriend("貂蝉");
GirlFriend girlFriend22 = GirlFriendFactory.getGirlFriend("西施");
System.out.println(girlFriend1 == girlFriend11);//true
System.out.println(girlFriend2 == girlFriend22);//true
}
}
复制代码
现实中,女朋友不让我去体验共享女朋友,在代码世界还是我说的算。
我正在享受这个被多个女友包围的快乐中,突然间我女朋友闯进了我的房间。
女朋友:看把你能耐的… 这聪明才智用到“点“上,这都能上天了。你给我滚?,不想理你了。
我:哦,那我滚。我滚啊滚,滚啊滚,滚到你怀里。
女朋友:扑哧一笑,讨厌…
我:走,咱们吃火锅去。
女朋友:好耶,好耶。
我:(暗自窃喜,终于躲过一劫,女人吗,没有什么烦恼不是吃一顿能解决的,不行的话,就吃两顿)。