设计模式之八式之第七式 享元模式(结构型)

实现方式

享元模式可能大家对定义什么的非常了解,但是今天我们先从实现开始逐步去分析;

	interface Setting
	{
	    public function init(int $userId);
	}

	class UserSetting implements Setting
	{
	    private $userId;
	
	    public function init(int $userId) : self {
	
	        $this->userId = $userId;
	        return $this;
	    }
	    
	    public function getPayMethod() : string {
	        return '获取'.$this->userId.'配置';
	    }
	}

	class SettingFactory
	{
	    private static $settings = [];
	
	    // 获取配置
	    public function getSetting(int $userId)
	    {
	        if (! isset(self::$settings[$userId])) {
	            self::$settings[$userId] = (new UserSetting())->init($userId);
	        }
	
	        return self::$settings[$userId];
	    }
	}
	
	$settingFactory = new SettingFactory();
	
	$userSetting = $settingFactory->getSetting(2);
	
	echo $userSetting->getPayMethod();

// 输出的值为 “获取2配置”

具象的表达

首先定义一个配置初始化的接口(Setting),在创建用户配置类(UserSetting)实现这个接口的init方法,接着在创建一个SettingFactory工厂用于创建配置的享元模型。在工厂中我定义了一个静态变量(类型为数组),将userId作为key。UserSetting 类作为值存储。这样就完成了对用户配置对象的保存。

官方的定义

摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共同的相同状态,从而让我们能在有限的内存容量中载入更多的对象。前提是享元对象是不可变对象。


核心解决的问题就是节约空间,使用的办法是找出相似对象之间的共有特征,然后复用这些特征。享元模式要解决的问题是节约内存空间大小,而缓存模式本质上是为了节省时间。

使用享元模式的意义

  • 减少内存消耗,节省服务器成本
  • 聚合同一类的不可变对象,提高对象复用性。

何时使用

  • 系统中有大量对象时
  • 这些对象消耗大量内存时
  • 这些对象的状态大部分可以外部化时。

优点

  • 可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份
  • 通过封装内存特有的运行状态,达到共享对象之间高效复用的目的。

缺点

  • 以时间换空间,间接增加了系统的实现复杂度
  • 运行时间更长,对于一些需要快速响应的系统并不合适。

总结

享元模式为共享对象定义了一个很好的结构范例,不过,用好享元模式的关键在于找到不可变对象。

课外扩展

Laravel中的IOC容器可以看作是一种享元模式的实现,它把对象保存在数组中,在需要的时候通过闭包机制进行取用,也有一些类共享一些状态属性的内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值