首页 > 代码库 > 设计模式之享元模式
设计模式之享元模式
享元模式(FlyWeight)
享元模式是设计模式中少数几个以提高系统性能为目的的设计模式。他的核心思想是:如果一个系统中存在多个相同的对象,那么只需共享一份对象的拷贝,而不必为每一次使用都创建新的对象。
在享元模式中,由于需要构造和维护这些可以共享的对象,因此需要一个工厂类用于维护和创建共享对象。
享元模式实现
- FlyWeightFactory享元工厂类
- 创建并管理享元对象,享元池一般设计成键值对,即用Map存储
- FlyWeight:抽象享元类
- 通常是一个接口或者抽象类,声明公开的方法,这些方法可以向外界提供对象的内部状态,设置外部状态
- ConcreteFlyWeight:具体享元类
- 为内部状态提供成员变量进行存储
- UnSharedConcreteFlyWeight:非共享享元类
- 不能被共享的子类可以设计为非共享享元类
- 不能被共享的子类可以设计为非共享享元类
举例说明
如果需要做一款扑克牌游戏(不考虑大小王),扑克总共52张,我们平时可能考虑创建52个不同的对象即可。但是可以发现,这些扑克牌不就是分为四类(红桃:Heart;黑桃:Spade;方块:Diamond;梅花:Club),每类不同的就是牌面A-K。
用享元模式设计如下:
(1)枚举定义扑克类型
/** * CardType 扑克牌类型 * @author yangkj */public enum CardType { //红桃:Heart;黑桃:Spade;方块:Diamond;梅花:Club HEART,SPADE,DIAMOND,CLUB}
(2)非共享享元类(这里当然就是牌面)
/** * CardBasic 扑克牌牌面 * @author yangkj*/public class CardBasic { /** * 牌面值 */ private String numbber; public String getNumbber() { return numbber; } public void setNumbber(String numbber) { this.numbber = numbber; } public CardBasic(String numbber) { super(); this.numbber = numbber; } public CardBasic() { super(); }}
(3)抽象享元接口 及 具体享元类
/** * Card 抽象享元接口 * @author yangkj*/public interface Card {void display(CardBasic basic);}/**
* CardEntity 具体享元类
* @author yangkj
*/class CardEntity implements Card { // 共享的属性 private CardType type; @Override public void display(CardBasic basic) { System.out.println("扑克牌花色:"+type); System.out.println("扑克牌牌面:"+basic.getNumbber()); } public CardEntity(CardType type) { super(); this.type = type; }}
(4)享元工厂类
/** * CardFactory 享元工厂类 * @author yangkj*/public class CardFactory { private static Map<String,Card> map = new HashMap<>(); public static Card getCardInstance(CardType type){ if(null !=map.get(type)){ return map.get(type); }else{ Card card = new CardEntity(type); map.put(type.name(), card); return card; } }}
(5)测试类
public static void main(String[] args) { /** * 创建四种扑克牌花色(共享享元实体) */ Card cardHeart = CardFactory.getCardInstance(CardType.HEART); Card cardClub = CardFactory.getCardInstance(CardType.CLUB); Card cardDiamond = CardFactory.getCardInstance(CardType.DIAMOND); Card cardSpade = CardFactory.getCardInstance(CardType.SPADE); /** * 创建扑克牌牌面(非共享享元) */ CardBasic basic8 = new CardBasic("8"); CardBasic basic10 = new CardBasic("10"); /** * 组装 */ cardHeart.display(basic8); cardDiamond.display(basic8); cardClub.display(basic10); cardSpade.display(basic10); }
(6)测试结果
享元模式应用场景
- 享元模式由于其共享的特性,可以用于”池“,如线程池、数据库连接池
- String类的设计也是享元模式,我们知道String内容是存放在常量池中
享元模式优缺点
- 优点
- 极大减少内存中对象的数量
- 相同或相似对象在内存中只存一份,极大节约内存资源,提高了系统性能
- 外部状态相对独立,不影响内部状态
- 缺点
- 模式较复杂,会使得程序逻辑变得复杂
- 为了节省类存,共享了内部状态,分离出外部状态,而读取外部状态使得运行时间变长,用时间换空间
设计模式之享元模式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。