善用设计模式-享元模式

   享元模式(Flyweight)是设计模式中少数几个以提高系统性能为目的的模式之一。它的核心思想是:如果在一个系统中存在多个相同的对象,那么只需共享一份对象的拷贝,而不必为每一次使用都创建新的对象,这样可以节省重复创建对象的内存和时间开销。由于需要构造和维护这些可以共享的对象,因此,常常会出现一个工厂类,用于维护和创建对象。

   享元模式分为内蕴状态和外蕴状态。内蕴状态就是共性,外蕴状态就是个性了。内蕴状态存储在享元内部,不会随环境的改变而有所不同,是可以共享的;外蕴状态是不可以共享的,它随环境的改变而改变的,因此外蕴状态是由客户端来保持(因为环境的变化是由客户端引起的)。在每个具体的环境下,客户端将外蕴状态传递给享元,从而创建不同的对象出来

   使用场景示例:有一个人事管理系统,假设公司甲,乙,丙共用这个系统,每个公司又有100个员工,每个公司员工都可以登录这个系统查询自己的收入情况,并且为了系统安全,每个公司都有自己独立的数据库,这种情况下,就可以使用享元模式为每个公司分别提供工资查询的接口,而一个公司下的所有员工可以共享一个查询(共享数据库连接)。

  接下来,看具体实现代码。

/**
 * @author pengl
 * 2014-5-3
 * 描述:享元接口
 */
public interface IReportManager {
	public String createReport();
}

/**
 * 
 * @author pengl
 * 2014-5-3
 * 描述:具体享元类一:创建财务报表
 */
public class FinancialReportManager implements IReportManager {
	protected String companyId = null;
	/**
	 * 外蕴状态 【个性】  在构造方法中给内蕴状态赋值
	 * @param companyId
	 */
	public FinancialReportManager(String companyId){
		this.companyId = companyId;
	}
	/**
	 * 内蕴状态 【共性】
	 */
	public String createReport() {
		return "This is a financial report from company " + companyId;
	}
}

/**
 * @author pengl
 * 2014-5-3
 * 描述:具体享元类二:创建员工报表
 */
public class EmployeeReportManager implements IReportManager{
	protected String companyId = null;
	/**
	 * 外蕴状态 【个性】 在构造方法中给内蕴状态赋值
	 * @param companyId
	 */
	public EmployeeReportManager(String companyId){
		this.companyId = companyId;
	}
	/**
	 * 内蕴状态 【共性】
	 */
	public String createReport() {
		return "This is a employee report from company " + companyId;
	}
}

/**
 * @author pengl
 * 2014-5-3
 * 描述:享元工厂类
 */
public class ReportManagerFactory {
	private Map<String, IReportManager> financialReportManager = 
			new HashMap<String, IReportManager>();
	private Map<String, IReportManager> employeeReportManager = 
			new HashMap<String, IReportManager>();
	/**
	 * 根据公司ID获取公司财务报表
	 * @param companyId
	 * @return
	 */
	IReportManager getFinancialReportManager(String companyId){
		IReportManager r = financialReportManager.get(companyId);
		if(r==null){
			r = new FinancialReportManager(companyId);
			financialReportManager.put(companyId, r);
		}
		return r;
	}
	/**
	 * 根据公司ID获取公司员工报表
	 * @param companyId
	 * @return
	 */
	IReportManager getEmployeeReportManager(String companyId){
		IReportManager r = employeeReportManager.get(companyId);
		if(r==null){
			r = new EmployeeReportManager(companyId);
			employeeReportManager.put(companyId, r);
		}
		return r;
	}
}

/**
 * @author pengl
 * 2014-5-3
 * 描述:客户端调用
 */
public class Main {
	public static void main(String[] args) {
		ReportManagerFactory factory = new ReportManagerFactory();
		IReportManager fReport = factory.getFinancialReportManager("A");
		System.out.println(fReport.createReport());
		IReportManager eReport = factory.getEmployeeReportManager("B");
		System.out.println(eReport.createReport());
		IReportManager fReport2 = factory.getFinancialReportManager("A");
		System.out.println(fReport2.createReport());
		IReportManager eReport2 = factory.getEmployeeReportManager("B");
		System.out.println(eReport2.createReport());
		System.out.println(fReport==fReport2);
		System.out.println(eReport==eReport2);
	}
}

控制台输出:

This is a financial report from company A
This is a employee report from company B
This is a financial report from company A
This is a employee report from company B
true
true
可以看出,同一个公司的调用是共用同一个对象。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值