设计模式 - 创造 - 工厂模式
工厂模式:通过把创建对象的代码包装起来,做到创建对象的代码与具体的业务逻辑代码相隔离的目的。
简单工厂
// 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(); } }
静态工厂
// 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'); } }
工厂方法
// 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(); } }
本作品采用《CC 协议》,转载必须注明作者和本文链接