初识设计模式——亨元模式(Flyweight Pattern)

亨元模式(Flyweight Pattern),其运用共享技术有效的支持大量颗粒度的对象。亨元模式可以避免大量非常相似类的开销。
详解
在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,那么把那些参数移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。
亨元是什么意思
“亨元” 并非日常常见词汇,在亨元模式语境里,“亨” 有共享的含义,“元” 可理解为基本元素、单元。亨元模式里,“亨元” 代表可共享的细粒度对象,借助共享这些对象达成高效利用资源的目的。
亨元模式的构成
- 抽象享元角色(Flyweight):此为所有具体享元类的抽象基类或者接口,规定了具体享元类需要实现的方法。
- 具体享元角色(Concrete Flyweight):实现抽象享元角色所定义的方法,存储内部状态。内部状态指的是不依赖外部环境,可在不同上下文中共享的状态。
- 非共享具体享元角色(Unshared Concrete Flyweight):并非所有享元模式都有此角色,它是不可共享的具体享元类,通常包含外部状态。外部状态是随环境变化而变化、不可共享的状态。
- 享元工厂角色(Flyweight Factory):负责创建和管理享元对象,维护一个享元池(通常是一个集合),当请求一个享元对象时,先查看享元池是否存在该对象,若存在则直接返回,若不存在则创建并放入享元池。
示例
场景介绍
在一个电商网站中,商品分类信息是相对固定且会被频繁使用的。我们可以使用享元模式来管理商品分类对象,减少内存开销。
代码
1 |
|
代码解释
在上述示例中,CategoryFlyweight 是抽象享元角色,ConcreteCategoryFlyweight 是具体享元角色,CategoryFlyweightFactory 是享元工厂角色。通过享元工厂来管理商品分类对象,当需要相同分类的对象时,直接从享元池中获取,避免了重复创建对象,从而减少了内存开销。
UML类图
享元模式的优缺点
优点
- 减少内存占用:通过共享对象,减少了系统中对象的数量,降低了内存开销。
- 提高性能:减少了对象的创建和销毁过程,提高了系统的响应速度。
缺点
- 增加系统复杂度:需要引入享元工厂来管理享元对象,增加了系统的复杂度。
- 线程安全问题:如果多个线程同时访问和修改享元对象的外部状态,可能会出现线程安全问题。
享元模式的适用场景
- 系统中存在大量相似对象:像游戏里的大量士兵、建筑等,这些对象很多属性是相同的,可通过享元模式共享相同属性,减少内存开销。
- 需要缓冲池的场景:例如数据库连接池、线程池等,通过共享连接或线程对象,降低频繁创建和销毁对象的开销。
- WEB 开发中的缓存:对于一些频繁使用且不常变化的数据,如菜单数据、配置信息等,可采用享元模式进行缓存,提升系统性能。