设计模式之享元模式

享元模式

享元模式是设计模式中少数几个以提高系统性能为目的的模式,比比较简单。它的核心思想是:如果在系统存在多个相同的对象,那么只需要共享一份对象的拷贝即可,不必为每一次使用都创建新的对象。在这种模式中,由于需要构造和维护可以共享的对象,所以会出现一个工厂类,用于维护和创建对象。
享元模式对性能的提升主要在以下几个方面:
1.可以节省重复创建对象的开销,因为被享元模式维护的形同对象只会被创建一次,当创建对象比较耗时时,便可以节省大量时间。
2.由于创建的对象数量减少,所以对系统的内存占用也小,这使得GC压力也相对降低,从而使系统拥有一个更健康的内存结构和更快的反应速度。
享元模式主要有享元工厂、抽象享元、具体享元类和主函数构成。享元工厂用域创建具体的享元类,维护相同的享元对象。它保证相同的享元对象可以被系统共享,即其内部使用了类似于单例模式的算法,当主函数请求的对象已经在系统存在时,返回已创建对象,不存在时再创建对象。抽象享元时定义需共享的对象的业务接口。享元类时为了实现某些特定的业务逻辑,而抽象享元便定义了这些逻辑的语义行为。
享元工厂是享元模式的核心,它需要确保系统可以共享相同的对象。一般情况下,享元工厂都会维护一个对象列表,当任何组件尝试获取享元类时,如果请求的享元类已经被创建,则直接返回已有的享元类,若没有被创建,则创建一个新的享元对象,并将它加入到维护队列中。享元模式用的比较多的场景就是复用大对象也就是重量级对象,它占用的内存空间和创建时间都比较耗资源。
例如某SAAS运营厂商,支持多租户模式。甲乙两家公司都是该厂商的客户,每一个公司定义为一个租户。每个公司的员工都可以查看自己的收入情况,为了系统安全,每个租户都有自己独立的数据库。在这种情况下,可以使用享元模式为每个租户分别提供工资查询接口,而每一个公司下的所有员工都可以共享一个查询,这样有多少个租户就意味着有多少个享元实例。

package pdfdemo;
import java.util.HashMap;
import java.util.Map;
public class ReportManagerFactory {
      Map<String,IReportManager> financialReportManager = new HashMap<String,IReportManager>();
      public IReportManager getFinancialReportManager(String tenantId) {
    	  IReportManager r = financialReportManager.get(tenantId);
    	  if(r == null) {
    		  r = new FinancialReportManager(tenantId);
    		  financialReportManager.put(tenantId,r);
    	  }
    	  return r;
      }
}
package pdfdemo;
public class FinancialReportManager implements IReportManager{
    protected String tenantId = null;
    public FinancialReportManager(String tenantId) {
    	this.tenantId = tenantId;
    }
	@Override
	public String createReport() {
		// TODO Auto-generated method stub
		return "This is a financial report";
	}
}
package pdfdemo;
public interface IReportManager {
    public String createReport();
}

总结

享元模式看起来和线程池有点像,但线程池里面维护的线程对象都是等价的,没有任何差别。而享元工厂维护的对象列表是专属的、唯一的,不可互相替代,他们都有各自的定义和应用,这也是线程池和享元模式最大的差异。

你可能感兴趣的:(设计模式,设计模式,享元模式)