1.9. 정적 팩토리 (Static Factory)

1.9.1. 사용 목적

이 패턴은 추상 팩토리와 유사하고, 종속 객체들이나 연관된 집합을 만드는데 사용합니다. 이 패턴과 추상 팩토리 패턴 사이의 차이점은 정적 팩토리 패턴은 만들 수 있는 모든 타입의 객체를 만드는 오직 단 하나의 정적인 메서드를 사용한다는 것입니다. 이 패턴은 보통 factory 또는 ``build``라고 합니다.

1.9.2. 예시

  • Zend Framework: Zend_Cache_Backend 또는 ``_Frontend``는 팩토리 메서드를 사용하고 캐시 백엔드 또는, 프론트엔드를 만듭니다.

1.9.3. UML 다이어그램

Alt StaticFactory UML Diagram

1.9.4. 코드

코드는 또한 GitHub 에서 볼 수 있습니다.

StaticFactory.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

namespace DesignPatterns\Creational\StaticFactory;

/**
 * Note1: Remember, static => global => evil
 * Note2: Cannot be subclassed or mock-upped or have multiple different instances
 */
class StaticFactory
{
    /**
     * the parametrized function to get create an instance
     *
     * @param string $type
     *
     * @static
     *
     * @throws \InvalidArgumentException
     * @return FormatterInterface
     */
    public static function factory($type)
    {
        $className = __NAMESPACE__ . '\Format' . ucfirst($type);

        if (!class_exists($className)) {
            throw new \InvalidArgumentException('Missing format class.');
        }

        return new $className();
    }
}

FormatterInterface.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php

namespace DesignPatterns\Creational\StaticFactory;

/**
 * Class FormatterInterface
 */
interface FormatterInterface
{
}

FormatString.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php

namespace DesignPatterns\Creational\StaticFactory;

/**
 * Class FormatString
 */
class FormatString implements FormatterInterface
{
}

FormatNumber.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php

namespace DesignPatterns\Creational\StaticFactory;

/**
 * Class FormatNumber
 */
class FormatNumber implements FormatterInterface
{
}

1.9.5. 테스트

Tests/StaticFactoryTest.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

namespace DesignPatterns\Creational\StaticFactory\Tests;

use DesignPatterns\Creational\StaticFactory\StaticFactory;

/**
 * Tests for Static Factory pattern
 *
 */
class StaticFactoryTest extends \PHPUnit_Framework_TestCase
{

    public function getTypeList()
    {
        return array(
            array('string'),
            array('number')
        );
    }

    /**
     * @dataProvider getTypeList
     */
    public function testCreation($type)
    {
        $obj = StaticFactory::factory($type);
        $this->assertInstanceOf('DesignPatterns\Creational\StaticFactory\FormatterInterface', $obj);
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testException()
    {
        StaticFactory::factory("");
    }
}