制造工具的工厂模式工厂模式是所有设计模式中最常见也是最容易理解的设计模式。工厂模式用最通俗的语言解释就是:把对象的创建交给工厂。工厂模式分析在编写面向对象的程序时,创建新对象(newObject)是一个非常重要的环节。那么当你需要根据不同的参数和场景选择创建不同的对象时,尤其是当这些类具有相同的抽象(接口)时,工厂模式可以很好地为你提供设计思路。详细来说,工厂模式可以分为:简单工厂、工厂方法、抽象工厂。他们的关系是从前到后,抽象层次逐渐递增。如果对建模理论有所了解,那么抽象建模的层次和模型的通用性之间的关系应该就很清楚了。一般来说,模型越抽象,适用范围越广,反之,模型越具体,适用范围就很有限。刚才提到的三款厂房车型也是如此。三种工厂模式比较对于简单工厂,其抽象层次较低,工厂类一般不包含复杂的对象生成逻辑,只能用于生成关联相对简单、可扩展性要求不高的对象。与简单工厂相比,工厂方法具有相对更高的抽象层次。工厂方法不仅需要对工厂生成的产品类进行抽象,还需要对工厂类进行抽象。当我们需要进一步建模,即对工厂生产的产品进行分类时,抽象工厂就可以派上用场了。在抽象工厂的定义中,增加了产品类可以在不同抽象中实现的定义,适用于需要工厂对象创建不同类型产品类的场景。虽然我们知道,抽象的层次越高,适用的场景就会越多。但是,从简单工厂、工厂方法、抽象工厂的对象关系图也可以看出,抽象层次越高,对象之间的关系就越复杂。说白了,当我们使用更高层次的抽象时,意味着我们需要实现更多的类和逻辑,才能让深度抽象落地。那么,如果我们的对象逻辑本身就很复杂,工厂实现在整体代码中的比例就很低。相反,如果我们的对象逻辑本身很简单,那么工厂实现在整体代码中的比例就很高。当我们选择使用哪种设计模式时,比如简单工厂的抽象层次较低,那么在对其进行扩展(增加对象逻辑关系)时,需要增加或改写的代码就比较多,这就是对于经常添加新的非常重要。对象类型会造成很多麻烦。但是也正是因为抽象层次低,我们不需要在代码中实现过多的抽象代码,可以减少这部分的代码量和处理逻辑。所以,选择哪家工厂来指导我们的设计,需要根据具体的业务场景进行权衡选择。Laravel中创建Redis连接的设计Laravel中很多地方都使用了工厂模式,这也体现了工厂模式的基础性和广泛适用性。这里,我们选择Laravel的Redis模块中Redis连接创建部分的代码作为示例,展示工厂模式在Laravel中的体现。在Laravel的Redis模块中,支持两种Redis连接驱动:PHPRedis扩展和Predis工具包。为了更方便的管理和使用Redis连接驱动及其对应的连接,Laravel添加了RedisManager对象定义。RedisManager对象既是Redis连接的管理者,也是Redis连接的创建工厂。首先我们看一下Reids连接和Laravel中对应工厂的关系。通过我们之前对工厂模式的介绍,可以很容易的认识到这是一种典型的工厂方法结构编程。连接创建工厂所有连接创建工厂都继承自IlluminateContractsRedisFactory接口。namespaceIlluminateContractsRedis;interfaceFactory{/***获取Redis连接*/publicfunctionconnection($name=null);}在Laravel中,Redis连接创建工厂目前只有一个实现类,就是IlluminateRedisRedisManager,它也是一个连接管理器和创建工厂的类。然后在RedisManager实现类中,Laravel通过创建不同的连接器来创建不同的Redis连接对象。namespaceIlluminateRedis;classRedisManagerimplementsFactory{/***获取Redis连接*/publicfunctionconnection($name=null){$name=$name?:'default';//如果存在则获取连接(这是连接管理器的功能)if(isset($this->connections[$name])){return$this->connections[$name];}//如果连接不存在,创建连接实例return$this->connections[$name]=$this->resolve($name);}/***创建Redis连接*/publicfunctionresolve($name=null){$name=$name?:'default';$options=$this->config['options']??[];if(isset($this->config[$name])){//先获取连接器,然后通过连接器创建连接return$this->connector()->connect($this->config[$姓名],$选项);}if(isset($this->config['clusters'][$name])){//这是创建的集群连接对象return$this->resolveCluster($name);}抛出新的InvalidArgumentException("Redisconnection[{$name}]notconfigured.");}/***获取Redisconnector*/protectedfunctionconnector(){//这里是factory的key,不同的连接,由不同的connector创建,So有个工厂选择流程开关($this->driver){case'predis':returnnewConnectorsPredisConnector;case'phpredis':returnnewConnectorsPhpRedisConnector;}}}创建一个工厂对象的展示,大家应该更容易在实际设计中理解工厂模式的逻辑,限于篇幅,没有完整的呈现Redis模块中连接相关的代码。但是相信通过对工厂模式的解读和在Redis中的梳理出了模块中主体的实现,大家可以通过Laravel源码阅读Laravel设计的Redis连接创建工厂,另外,Laravel中还有很多工厂方法,比如数据库connectio的创建工厂n在数据库中,视图引擎中的视图引擎。工厂的创建等。这些都是工厂模式设计的好例子
