实现创建对象的代码与具体业务逻辑代码相隔离工厂模式:通过把创建对象的代码包装起来,做到创建对象的代码与具体的业务逻辑代码相隔离的目的。
简单工厂
// Log.php
namespace Creational\SimpleFactory;
interface Log
{
public function write();
}
// DataLog.php
namespace Creational\SimpleFactory;
class DataLog implements Log
{
public function write()
{
}
}
//FileLog.php
namespace Creational\SimpleFactory;
class FileLog implements Log
{
public function write()
{
}
}
//SimpleFactory.php
namespace Creational\SimpleFactory;
class SimpleFactory
{
public function bulid($name = 'FileLog')
{
switch ($name) {
case 'DataLog':
return new DataLog();
break;
default:
return new FileLog();
break;
}
}
}
//SimpleFactoryTest.php
namespace Tests;
use Creational\SimpleFactory\SimpleFactory;
use Creational\SimpleFactory\FileLog;
use Creational\SimpleFactory\DataLog;
use PHPUnit\Framework\TestCase;
class SimpleFactoryTest extends TestCase
{
public function testSfFile()
{
$factory = new SimpleFactory();
$log = $factory->bulid();
$this->assertInstanceOf(FileLog::class, $log);
$log->write();
} public function testSfDatabase()
{
$factory = new SimpleFactory();
$log = $factory->bulid('DataLog');
$this->assertInstanceOf(DataLog::class, $log);
$log->write();
}
}
工厂方法
// Car.php
namespace Creational\FuncFactory;
interface Car
{
public function run();
}
// HondaCar.php
namespace Creational\FuncFactory;
class HondaCar implements Car
{
public function run()
{
}
}
// ToyotaCar.php
namespace Creational\FuncFactory;
class ToyotaCar implements Car
{
public function run()
{
}
}
// FuncFactory.php
namespace Creational\FuncFactory;
interface FuncFactory
{
public function build();
}
// HondaFactory.php
namespace Creational\FuncFactory;
use Creational\FuncFactory\HondaCar;
class HondaFactory implements FuncFactory
{
public function build()
{
return new HondaCar();
}
}
// ToyotaFactory.php
namespace Creational\FuncFactory;
use Creational\FuncFactory\ToyotaCar;
class ToyotaFactory implements FuncFactory
{
public function build()
{
return new ToyotaCar();
}
}
namespace Tests;
use Creational\FuncFactory\HondaCar;
use Creational\FuncFactory\ToyotaCar;
use Creational\FuncFactory\ToyotaFactory;
use Creational\FuncFactory\HondaFactory;
use PHPUnit\Framework\TestCase;
class FuncFactoryTest extends TestCase
{
public function testTf()
{
$tfactory = new ToyotaFactory();
$tcar = $tfactory->build();
$this->assertInstanceOf(ToyotaCar::class, $tcar);
$tcar->run();
}
public function testHf()
{
$hfactory = new HondaFactory();
$hcar = $hfactory->build();
$this->assertInstanceOf(HondaCar::class, $hcar);
$hcar->run();
}
}
抽象工厂
// Car.php
namespace Creational\AbstractFactory;
interface Car
{
public function run();
}
// ToyotaCar.php
namespace Creational\AbstractFactory;
class ToyotaCar implements Car
{
public function run()
{
}
}
// HondaCar.php
namespace Creational\AbstractFactory;
class HondaCar implements Car
{
public function run()
{
}
}
// Engine.php
namespace Creational\AbstractFactory;
interface Engine
{
public function doSomeing();
}
// HondaEngine.php
namespace Creational\AbstractFactory;
class HondaEngine implements Engine
{
public function doSomeing()
{
}
}
// ToyotaEngine.php
namespace Creational\AbstractFactory;
class ToyotaEngine implements Engine
{
public function doSomeing()
{
}
}
// AbstractFactory.php
namespace Creational\AbstractFactory;
abstract class AbstractFactory
{
public function build(){}
public function buildEngine(){}
public function buildTire()
{
}
}
// HondaFactory.php
namespace Creational\AbstractFactory;
use Creational\AbstractFactory\HondaCar;
use Creational\AbstractFactory\HondaEngine;
class HondaFactory extends AbstractFactory
{
public function build()
{
return new HondaCar();
}
public function buildEngine()
{
return new HondaEngine();
}
}
// ToyotaFactory.php
namespace Creational\AbstractFactory;
use Creational\AbstractFactory\ToyotaCar;
use Creational\AbstractFactory\ToyotaEngine;
class ToyotaFactory extends AbstractFactory
{
public function build()
{
return new ToyotaCar();
}
public function buildEngine()
{
return new ToyotaEngine();
}
}
// AbstractFactoryTest.php
namespace Tests;
use Creational\AbstractFactory\HondaCar;
use Creational\AbstractFactory\ToyotaCar;
use Creational\AbstractFactory\ToyotaFactory;
use Creational\AbstractFactory\HondaFactory;
use Creational\AbstractFactory\ToyotaEngine;
use Creational\AbstractFactory\HondaEngine;
use PHPUnit\Framework\TestCase;
class AbstractFactoryTest extends TestCase
{
public function testTf()
{
$tfactory = new ToyotaFactory();
$tcar = $tfactory->build();
$te = $tfactory->buildEngine();
$tt = $tfactory->buildTire();
$this->assertInstanceOf(ToyotaCar::class, $tcar);
$this->assertInstanceOf(ToyotaEngine::class, $te);
$tcar->run();
}
public function testHf()
{
$hfactory = new HondaFactory();
$hcar = $hfactory->build();
$he = $hfactory->buildEngine();
$ht = $hfactory->buildTire();
$this->assertInstanceOf(HondaCar::class, $hcar);
$this->assertInstanceOf(HondaEngine::class, $he);
$hcar->run();
}
}
静态工厂
// Format.php
namespace Creational\StaticFactory;
interface Format
{
public function format();
}
// NumberFormat.php
namespace Creational\StaticFactory;
class NumberFormat implements Format
{
public function format()
{
}
}
// StringFormat.php
namespace Creational\StaticFactory;
class StringFormat implements Format
{
public function format()
{
}
}
// StaticFactory.php
namespace Creational\StaticFactory;
use InvalidArgumentException;
class StaticFactory
{
public static function factory(String $type)
{
if($type == 'Number'){
return new NumberFormat();
}elseif($type == 'String'){
return new StringFormat();
}
throw new InvalidArgumentException('Unknown format given');
}
}
// StaticFactoryTest.php
namespace Tests;
use Creational\StaticFactory\NumberFormat;
use Creational\StaticFactory\StaticFactory;
use PHPUnit\Framework\TestCase;
use InvalidArgumentException;
class StaticFactoryTest extends TestCase
{
public function testSf()
{
$format = StaticFactory::factory('Number');
$this->assertInstanceOf(NumberFormat::class ,$format);
}
public function testEx()
{
$this->expectException(InvalidArgumentException::class);
StaticFactory::factory('object');
}
}