享元模式

享元模式

最近和女朋友出去逛街,看到了一个让我心跳加速的事情:共享女友。

可惜我有女朋友了,不然… 你懂得….

看到这一幕让我有点似曾相识的感觉,这不就是设计模式中的享元模式吗?在一个池中,共享对象。

一、享元模式(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

    }
}

复制代码

现实中,女朋友不让我去体验共享女朋友,在代码世界还是我说的算。

我正在享受这个被多个女友包围的快乐中,突然间我女朋友闯进了我的房间。

女朋友:看把你能耐的… 这聪明才智用到“点“上,这都能上天了。你给我滚?,不想理你了。

我:哦,那我滚。我滚啊滚,滚啊滚,滚到你怀里。

女朋友:扑哧一笑,讨厌…

我:走,咱们吃火锅去。

女朋友:好耶,好耶。

我:(暗自窃喜,终于躲过一劫,女人吗,没有什么烦恼不是吃一顿能解决的,不行的话,就吃两顿)。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享