设计模式-享元模式

转眼就要 6 月份了,时间过的好快勒。

说到享元模式,第一个想到的应该就是池技术了,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。

比如我们每次创建字符串对象时,都需要创建一个新的字符串对象的话,内存开销会很大,所以如果第一次创建了字符串对象“adam“,下次再创建相同的字符串”adam“时,只是把它的引用指向”adam“,这样就实现了”adam“字符串再内存中的共享。

举个最简单的例子,网络联机下棋的时候,一台服务器连接了多个客户端(玩家),如果我们每个棋子都要创建对象,那一盘棋可能就有上百个对象产生,玩家多点的话,因为内存空间有限,一台服务器就难以支持了,所以这里要使用享元模式,将棋子对象减少到几个实例。下面给出享元模式的定义。

享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。UML结构图如下:
  在这里插入图片描述
  其中,Flyweight是抽象享元角色。它是产品的抽象类,同时定义出对象的外部状态和内部状态(外部状态及内部状态相关内容见后方)的接口或实现;ConcreteFlyweight是具体享元角色,是具体的产品类,实现抽象角色定义的业务;UnsharedConcreteFlyweight是不可共享的享元角色,一般不会出现在享元工厂中;FlyweightFactory是享元工厂,它用于构造一个池容器,同时提供从池中获得对象的方法。
  1. Flyweight抽象类
  所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。

public abstract class Flyweight {

    //内部状态
    public String intrinsic;
    //外部状态
    protected final String extrinsic;

    //要求享元角色必须接受外部状态
    public Flyweight(String extrinsic) {
        this.extrinsic = extrinsic;
    }

    //定义业务操作
    public abstract void operate(int extrinsic);

    public String getIntrinsic() {
        return intrinsic;
    }

    public void setIntrinsic(String intrinsic) {
        this.intrinsic = intrinsic;
    }

}
  1. ConcreteFlyweight类
      继承Flyweight超类或实现Flyweight接口,并为其内部状态增加存储空间。
public class ConcreteFlyweight extends Flyweight {

    //接受外部状态
    public ConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    //根据外部状态进行逻辑处理
    @Override
    public void operate(int extrinsic) {
        System.out.println("具体Flyweight:" + extrinsic);
    }

}

UnsharedConcreteFlyweight类

public class UnsharedConcreteFlyweight extends Flyweight {

    public UnsharedConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    @Override
    public void operate(int extrinsic) {
        System.out.println("不共享的具体Flyweight:" + extrinsic);
    }

}

FlyweightFactory类

public class FlyweightFactory {

    //定义一个池容器
    private static HashMap<String, Flyweight> pool = new HashMap<>();

    //享元工厂
    public static Flyweight getFlyweight(String extrinsic) {
        Flyweight flyweight = null;

        if(pool.containsKey(extrinsic)) {    //池中有该对象
            flyweight = pool.get(extrinsic);
            System.out.print("已有 " + extrinsic + " 直接从池中取---->");
        } else {
            //根据外部状态创建享元对象
            flyweight = new ConcreteFlyweight(extrinsic);
            //放入池中
            pool.put(extrinsic, flyweight);
            System.out.print("创建 " + extrinsic + " 并从池中取出---->");
        }

        return flyweight;
    }
}

client 端

public class Client {
    public static void main(String[] args) {
        Flyweight flyweight1 = FlyweightFactory.getFlyweight("X");
        FlyweightFactory.getFlyweight("Y");
        FlyweightFactory.getFlyweight("Z");
        Flyweight flyweight2 = FlyweightFactory.getFlyweight("X");
        Flyweight flyweight3 = new UnsharedConcreteFlyweight("X");

        if(flyweight1==flyweight2){
            System.out.println("flyweight1与flyweight2是同一个对象");
        }
        if(flyweight1==flyweight3|| flyweight2==flyweight3){
            System.out.println("flyweight1与flyweight3是同一个对象或flyweight2与flyweight3是同一个对象");
        }else {
            System.out.println("flyweight1与flyweight3不是同一个对象并且flyweight2与flyweight3不是同一个对象");
        }
    }
}

在这里插入图片描述

总结:享元模式其实可以把他作为一个全局变了取看待,这里主要是通过了 hashMap 作为存储,其实还可以用别的集合的方式取存储。都是为了减少对象的创建。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值