原标题:Laravel 中的简单工厂和抽象工厂
设计模式之工厂模式分为两种:简单工厂和抽象工厂模式,工厂模式属于“创建”型的设计模式,顾名思义用来实例化对象,调用者不需要关心对象的具体位置和实现,工厂模式隐藏了背后的细节,从而实现了解耦的目的。
在大多数面向对象的语言中,实例化对象基本上都是 newClassA()这样创建实例,有两个原因不建议这么做:1.上层使用者没有和对象的创建过程隔离,导致代码耦合度高 2.创建对象实例的过程可能比较复杂,比如一些前置的过程。所以把这个创建过程交给工厂方法,调用者不用关心实例是怎么创建的。
工厂是生产产品的,这里产品指的就是具体的实例。简单工厂和抽象工厂设计模式都是为了解决类的实例化,避免 newXX()带来的代码耦合。
简单工厂模式
简单工厂模式可以通过一个工厂方法,或者说一个函数,比如传入一个参数,工厂方法根据这个参数返回具体类的实例。它相当于多了一层封装,你只要关心需要什么实例,它就返回什么实例,而不用直接实例化,实例化的过程交给了工厂方法。
Laravel 中一个数据库连接的工厂类:
vendor/laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php
protectedfunctioncreateConnection($driver,$connection,$database,$prefix='',array $config=[])
{
if($this->container->bound($key="db.connection.{$driver}")){
return$this->container->make($key,[$connection,$database,$prefix,$config]);
}
switch($driver){
case'mysql':
returnnewMySqlConnection($connection,$database,$prefix,$config);
case'pgsql':
returnnewPostgresConnection($connection,$database,$prefix,$config);
case'sqlite':
returnnewSQLiteConnection($connection,$database,$prefix,$config);
case'sqlsrv':
returnnewSqlServerConnection($connection,$database,$prefix,$config);
}
thrownewInvalidArgumentException("Unsupported driver [$driver]");
}
这里根据配置文件数据库驱动的配置,返回对应数据库的连接对象的实例。
简单工厂模式符合 单一职责原则 ,也就是每个类只做一件事情,但不符合 开放封闭原则 ,每次增加和减少所需实例都需要改动代码,不能做到很好的扩展。
抽象工厂模式
抽象工厂模式在简单工厂模式基础上,多了一层抽象工厂接口,它的思想是,假如有多个工厂生产同样的产品,他们有同样的行为,那么把这些产品的创建行为抽象出来,每个工厂实现这个抽象接口。
适用场景
有多个工厂,生产同一类型的产品,如下所示:
工厂1
产品1 产品2 产品3 工厂2
产品1 产品2 产品3 以 Mac 系统和 Windows 系统为例,都有创建 button 和创建 border 功能,这两个工厂都可以生产 button 和 border,那么把创建这两个产品的方法抽象出来,这个抽象出来的方法叫做抽象工厂类,两个工厂都要实现这个抽象类。
PHP 抽象工厂代码示例:
abstractclassAbstractFactory{
abstractpublicfunctionCreateButton();
abstractpublicfunctionCreateBorder();
}
classMacFactoryextendsAbstractFactory{
publicfunctionCreateButton()
{
returnnewMacButton();
}
publicfunctionCreateBorder()
{
returnnewMacBorder();
}
}
classWinFactoryextendsAbstractFactory{
publicfunctionCreateButton()
{
returnnewWinButton();
}
publicfunctionCreateBorder()
{
returnnewWinBorder();
}
}
classButton{}
classBorder{}
classMacButtonextendsButton{
function__construct()
{
echo'MacButton is created'."n";
}
}
classMacBorderextendsBorder{
function__construct()
{
echo'MacBorder is created'."n";
}
}
classWinButtonextendsButton{
function__construct()
{
echo'WinButton is created'."n";
}
}
classWinBorderextendsBorder{
function__construct()
{
echo'WinBorder is created'."n";
}
}
?>
从工厂取出实例:
$type='Mac';//value by user.
if(!in_array($type,array('Win','Mac')))
die('Type Error');
$factoryClass=$type.'Factory';
$factory=new$factoryClass;
$factory->CreateButton();
$factory->CreateBorder();
责任编辑: