【设计模式In Java】十、享元模式

享元模式

定义

享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

场景

现有一个代理程序,接受用户的请求然后连接到目标主机上获取信息,然后返回给用户,其中目标主机只有一台,但是不同的业务数据可能会通过不同的连接方式获取,比如SHH、GRPC、TCP等。假设我们每次连接时都创建一个新的连接对象,不仅创建过程会消耗资源,甚至会因为任务拥堵导致创建大量相同的连接对象(同一个主机发起很多请求),它们之间的区别仅仅是请求不同,这时可以使用享元模式,把相同主机的连接对象保存起来,遇到相同的连接可以直接复用,这里只模拟连接目标主机的情况。

UML类图

简单的享元模式:
在这里插入图片描述
结合组合模式的享元模式:
在这里插入图片描述

代码

flyweight
示例:

public class TestFlyWeight {

    @Test
    public void test(){
        Connection sshConnection = ConnectionFactory.getConnection(ConnectionType.SSH);
        Connection grpcConnection = ConnectionFactory.getConnection(ConnectionType.GRPC);
        Connection tcpConnection = ConnectionFactory.getConnection(ConnectionType.TCP);

        sshConnection.connect();
        sshConnection.request("ssh cmd");
        grpcConnection.connect();
        grpcConnection.request("grpc cmd");
        tcpConnection.connect();
        tcpConnection.request("tcp cmd");

        Connection sshConnection1 = ConnectionFactory.getConnection(ConnectionType.SSH);
        Connection grpcConnection1 = ConnectionFactory.getConnection(ConnectionType.GRPC);
        Connection tcpConnection1 = ConnectionFactory.getConnection(ConnectionType.TCP);
        System.out.println(sshConnection1 == sshConnection);//true
        System.out.println(grpcConnection1 == grpcConnection);//true
        System.out.println(tcpConnection1 == tcpConnection);//true

        Connections connections = new Connections();
        connections.addConnections(Arrays.asList(sshConnection,grpcConnection1,tcpConnection1));
        connections.connect();
        connections.request("ssh cmd or grpc cmd");
        connections.shutdown();

    }

}

总结

当系统中存在大量相同或者相似的对象时,享元模式是一种较好的解决方案,它通过共享技术实现相同或相似的细粒度对象的复用,从而节约了内存空间,提高了系统性能。相比其他结构型设计模式,享元模式的使用频率并不算太高,但是作为一种以“节约内存,提高性能”为出发点的设计模式,它在软件开发中还是得到了一定程度的应用。

享元对象拥有内部状态和外部状态:内部状态是享元对象的公共状态,不会随环境变化而变化,比如本例中的连接ip;外部状态会跟随环境变化而变化,比如本例中执行的具体命令。普通享元模式的具体对象可以共享内部状态,但外部状态可能不同,但可以借助组合模式,让这些外部状态包装在组合里,外部状态看起来就会一致。内部状态和外部状态的分离给设计和理解带来困难,很多情况下内外部状态分离会导致设计的困难以及运行效率的降低,比如IO模块,如果公用一个通道,多个读取请求可能会出现等待,如果使用并发和异步IO,程序的设计、理解和维护又变得困难。

享元模式适用于那些可能出现大量相似对象,使用频率很高,并且可以区分出内部状态和外部状态的场景中,由于程序会在内存中维护一个享元池,如果享元对象使用的频率并不高,可能会造成内存浪费,可以需结合缓存、过期等技术来协调。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值