设计模式之享元模式
享元模式是一种常用的设计模式。尤其是在拥有大数据量的传统后台服务中尤为突出。我们往往在不知不觉中就使用了这个设计模式。
先来看看享元模式的定义:
Flyweight Pattern Flyweight
译为: n. 次最轻量级的拳击选手。 拳击比赛的重量级、轻量级是通过选手的体重来分界的。
享元模式就是通过在程序中“缓存”进而达到“共享”厚重对象,是虚拟机的内存瘦身,减少消耗的设计模式。它可以使一个原本应该很大型的数据服务进程尽可能的瘦下来。这种设计模式相对于其它的模式在理念(思想)上有所差距。这主要体(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )现在,大部分的设计模式,都是建立在通过对象结构来实现整体架构的低内聚、高耦合。从而使业务在变更和扩展时,软件系统可以很容易的适应。而享元模式的主要目的则是为了减少内存消耗,瘦身程序。这里插句题外话,记得之前看过一本书中说过,如果说计算机世界中新创造了什么划时代的思想的话,那么毫无疑问,就是缓存。
简单点来说,享元模式其实就是对重对进行缓存管理。使得对象只(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )需要创建一次,各个依赖的地方使用的对象映射到内存中,都是同一块地址的目的。 通过上边对设计模式的描述,经过思考我们可以看出,在这个设计模式中,我们需要用到三个元素:
下面来举一个具体的例子:
享元工厂
根据(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )ID创建、缓存、返回服务器实例
抽象享元类
银行服务器:查账、存款、转账、取款
具体享元类
工商银行服务器
交通银行服务器
建设银行服务器
代码实现:
享元工厂:
public class BankServerMgr { private BankServerMgr() { } private static final BankServerMgr instance = new BankServerMgr(); public static BankServerMgr getInstance() { return instance; } private Map<String, IBankServer> bankServerCache = new HashMap<>(); /** * 根据ID获取对应的银行服务器实例 * * @param bankID * @return */ public synchronized IBankServer getBankServer(String bankID) { IBankServer bankServer = bankServerCache.get(bankID); if (bankServer == null) { bankServer = createBankServerByID(bankID); bankServerCache.put(bankID, bankServer); } return bankServer; } /** * 根据银行ID创建服务器实例 * * @param bankID * @return */ private IBankServer createBankServerByID(String bankID) { if ("ICBC".equals(bankID)) { return new ICBCServer(); } if ("BCM".equals(bankID)) { return new BCMServer(); } if ("CCB".equals(bankID)) { return new CCBServer(); } return null; } }
抽象享元类:
public interface IBankServer { /** * 查询账户信息 * * @return */ int checkAccount(); /** * 转账 * * @return */ boolean transferAccount(int money, int accountID); /** * 存钱 * * @return */ int saveMoney(int money); /** * 取钱 * * @return */ int drawMoney(int money); }
具体享元类
public class ICBCServer implements IBankServer { @Override public int checkAccount() { // do sth in ICBC return 0; } @Override public boolean transferAccount(int money, int accountID) { // do sth in ICBC return true; } @Override public int saveMoney(int money) { // do sth in ICBC return 0; } @Override public int drawMoney(int money) { // do sth in ICBC return 0; } }
public class BCMServer implements IBankServer { @Override public int checkAccount() { // do sth in BCM return 0; } @Override public boolean transferAccount(int money, int accountID) { // do sth in BCM return false; } @Override public int saveMoney(int money) { // do sth in BCM return 0; } @Override public int drawMoney(int money) { // do sth in BCM return 0; } }
public class CCBServer implements IBankServer { @Override public int checkAccount() { // do sth in CCB return 0; } @Override public boolean transferAccount(int money, int accountID) { // do sth in CCB return true; } @Override public int saveMoney(int money) { // do sth in CCB return 0; } @Override public int drawMoney(int money) { // do sth in CCB return 0; } }