静态工厂模式(Static Factory)

目的

与抽象工厂模式类似,此模式用于创建一系列相关或相互依赖的对象。 『静态工厂模式』与『抽象工厂模式』的区别在于,只使用一个静态方法来创建所有类型对象, 此方法通常被命名为 factorybuild

例子

  • Zend Framework: Zend_Cache_Backend_Frontend 使用工厂方法创建缓存后端或前端

UML 图

file

代码

你可以在 GitHub 上找到这个代码。

StaticFactory.php

  1. <?php
  2. namespace DesignPatterns\Creational\StaticFactory;
  3. /**
  4. * 注意点1: 记住,静态意味着全局状态,因为它不能被模拟进行测试,所以它是有弊端的
  5. * 注意点2: 不能被分类或模拟或有多个不同的实例。
  6. */
  7. final class StaticFactory
  8. {
  9. /**
  10. * @param string $type
  11. *
  12. * @return FormatterInterface
  13. */
  14. public static function factory(string $type): FormatterInterface
  15. {
  16. if ($type == 'number') {
  17. return new FormatNumber();
  18. }
  19. if ($type == 'string') {
  20. return new FormatString();
  21. }
  22. throw new \InvalidArgumentException('Unknown format given');
  23. }
  24. }

FormatterInterface.php

  1. <?php
  2. namespace DesignPatterns\Creational\StaticFactory;
  3. interface FormatterInterface
  4. {
  5. }

FormatString.php

  1. <?php
  2. namespace DesignPatterns\Creational\StaticFactory;
  3. class FormatString implements FormatterInterface
  4. {
  5. }

FormatNumber.php

  1. <?php
  2. namespace DesignPatterns\Creational\StaticFactory;
  3. class FormatNumber implements FormatterInterface
  4. {
  5. }

测试

Tests/StaticFactoryTest.php

  1. <?php
  2. namespace DesignPatterns\Creational\StaticFactory\Tests;
  3. use DesignPatterns\Creational\StaticFactory\StaticFactory;
  4. use PHPUnit\Framework\TestCase;
  5. class StaticFactoryTest extends TestCase
  6. {
  7. public function testCanCreateNumberFormatter()
  8. {
  9. $this->assertInstanceOf(
  10. 'DesignPatterns\Creational\StaticFactory\FormatNumber',
  11. StaticFactory::factory('number')
  12. );
  13. }
  14. public function testCanCreateStringFormatter()
  15. {
  16. $this->assertInstanceOf(
  17. 'DesignPatterns\Creational\StaticFactory\FormatString',
  18. StaticFactory::factory('string')
  19. );
  20. }
  21. /**
  22. * @expectedException \InvalidArgumentException
  23. */
  24. public function testException()
  25. {
  26. StaticFactory::factory('object');
  27. }
  28. }