享元设计模式
创始人
2024-03-15 05:00:31
0

一、享元模式

1、定义

享元模式(Flyweight Pattern)又称作轻量级模式,是指提供减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒度的对象,将多个对同一对象的访问集中起来,不必为每个访问者都创建一个单独的对象,以此来降低内存的消耗,属于结构型设计模式。

享元模式是对象池的一种实现,类似线程池,线程池可以避免不停地创建和销毁对个对象,消耗性能。

享元模式的本质是缓存共享对象,降低内存消耗。

2、结构

(1)模式的结构

主要角色如下:

  • 抽象享元角色(IFlyweight):享元对象抽象基类或者接口,同时定义出了对象的外部状态和内部状态的接口或实现。
  • 具体享元角色(ConcreteFlyweight):实现抽象角色定义的业务。该角色的内部状态处理应该与环境无关,不会出现一个操作改变内部状态、同时修改了外部状态的情况。
  • 享元工厂(FlyweightFactory):负责管理享元对象池和创建享元对象。

(2)享元模式的内部状态和外部状态

享元模式把一个对象的状态分为内部状态和外部状态

  • 内部状态:指对象共享出来的信息,存储在享元对象内部,并且不会随环境的改变而改变。
  • 外部状态:指对象得以依赖的一个标记,随环境的改变而改变,不可共享。

比如:连接池中的连接对象,保存在连接对象中的用户名、密码、URL等信息,在创建对象时就已经设置好了,不会随环境的改变而改变,这些为内部状态。而当每个连接对象要被回收利用时,我们需要将它标记为可用状态,这些为外部状态。

3、优缺点

优点:

  • 减少对象的创建,降低了内存中对象的数量,降低系统的内存,提高效率。
  • 减少内存之外的其他资源占用。

缺点:

  • 关注内、外部状态,关注线程安全问题。
  • 使系统、程序的逻辑复杂。

4、使用场景

  • 经常应用于系统底层的开发,来解决系统的性能问题。
  • 系统有大量相似对象,需要缓冲池的场景。

5、在框架源码中使用

  • Java中的 String类,Integer类中的IntegerCache等。
  • Apache源码中的 对象池(GenericObjectPoo l)。

二、模式的通用实现

代码如下:

public class FlyweightPattern {public static void main(String[] args) {IFlyweight flyweight1 = FlyweightFactory.getFlyweight("i-aaa");IFlyweight flyweight2 = FlyweightFactory.getFlyweight("i-bbb");IFlyweight flyweight3 = FlyweightFactory.getFlyweight("i-aaa");flyweight1.operation("e-123");flyweight1.operation("e-456");flyweight3.operation("e2-123");}
}// 抽象享元角色interface IFlyweight{void operation(String extrinsicState);
}// 具体享元角色
class ConcreteFlyweight implements IFlyweight{private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}@Overridepublic void operation(String extrinsicState) {System.out.println("对象 哈希地址:" + System.identityHashCode(this));System.out.println("内部状态:" + this.intrinsicState);System.out.println("外部状态:" + extrinsicState);}
}// 享元工厂
class FlyweightFactory{private static Map pool = new HashMap<>();private FlyweightFactory() {}public static IFlyweight getFlyweight(String intrinsicState){// 由于内部状态具备不变性,所以作为缓存的键if(!pool.containsKey(intrinsicState)){IFlyweight flyweight = new ConcreteFlyweight(intrinsicState);pool.put(intrinsicState, flyweight);return flyweight;}return pool.get(intrinsicState);}
}

在这里插入图片描述

三、模式的应用实例

以数据库连接池为例,Connection连接对象再使用之前我们需要提前创建好并缓存起来,使用完毕之后,需要在放回去,来达到资源重复利用的目的。

public class ConnectionPool {private Vector pool;private String url = "jdbc:mysql://localhost:3306/test_db";private String username = "root";private String pazzword = "123456";private String driverClassName = "com.mysql.cj.jdbc.Driver";private int poolSize = 100;public ConnectionPool() {pool = new Vector<>(poolSize);try {Class.forName(driverClassName);for (int i = 0; i < poolSize; i++) {Connection conn = DriverManager.getConnection(url, username, pazzword);pool.add(conn);}} catch (Exception e) {e.printStackTrace();}}public synchronized Connection getConnection(){if(pool.size() > 0){Connection conn = pool.get(0);pool.remove(conn);return conn;}return null;}public synchronized void release(Connection conn){pool.add(conn);}}

测试:

	public static void main(String[] args) throws SQLException {ConnectionPool connectionPool = new ConnectionPool();Connection conn = connectionPool.getConnection();conn.setAutoCommit(false);conn.createStatement();//conn.commit();connectionPool.release(conn);}

– 求知若饥,虚心若愚。

相关内容

热门资讯

聚杰微纤(300819)披露制... 截至2025年12月25日收盘,聚杰微纤(300819)报收于28.81元,较前一交易日上涨3.0%...
康曼德资本董事长丁楹:A股将进... 2025年A股在政策、估值、盈利、资金四重支撑下走出了牛市行情,但市场细分赛道的分化却愈发明显。20...
缅甸妙瓦底KK园区等已被强力拆... 视频来源:公安部微信公众号 记者12月25日从公安部获悉,近日,公安部派出工作组会同缅甸、泰国执法部...
盐田港(000088)披露公司... 截至2025年12月25日收盘,盐田港(000088)报收于4.55元,较前一交易日上涨0.66%,...
952名缅甸妙瓦底地区涉电诈犯... 来源:人民日报客户端 中缅泰联合开展清剿缅甸妙瓦底地区 赌诈园区行动 952名缅甸妙瓦底地区涉电诈犯...
原创 新... 最近几个赛季,孙铭徽一直都被视为广厦的“小外援”,距离他上一次场均得分不到两位数,还要追溯到2018...
意大利要求Meta暂停禁止竞争... 意大利已下令Meta公司暂停其禁止企业在WhatsApp上使用商业工具提供自家AI聊天机器人的政策。...
山西证券(002500)披露现... 截至2025年12月25日收盘,山西证券(002500)报收于6.11元,较前一交易日上涨0.33%...