개방/폐쇄 원칙은 클래스의 핵심 동작 (즉, 소스 코드를 편집하지 않음)을 수정하지 않고 기능을 추가하기 위해 일부 코드를 확장하는 것과 관련이 있습니다. 클래스는 자체적으로 내부를 유지하고 상호 작용할 수있는 명확한 공용 인터페이스를 제공합니다. 이 관점에서 볼 때 개방/폐쇄 원칙을 어긴 것은 아닙니다. 적어도 액면 그대로.
그러나 내가 말한 바에 따르면 귀하의 개인용 $codeMap
어레이에 대한 설정자를 가지고 있다면 원리가 깨지는 지 궁금하다는 인상을 받았습니다. 직접 구현하지는 않지만, 다른 개발자가 $codeMap
어레이에 대한보다 미세 조정 된 액세스를 원할 경우 수정하는 것이 매력적입니다. 기본적으로이 배열을 즉시 업데이트하는 유일한 방법은이를 지우고 setCodeMap()
으로 다시 설정하는 것입니다. 맵에 단일 코드를 추가하는 메커니즘을 제공하지 않습니다. 이지도에 대한보다 세분화 된 액세스가 필요하면 즉시 공개/폐쇄 원칙을 위반하게됩니다.
다른 개발자가 코드를 사용하고 있고 $codeMap
배열이 20 또는 30 개의 요소로 충분하다고 가정 해 보겠습니다. 그들은 배열에 더 나은 액세스를 제공하기 위해 핵심 코드를 해킹해야합니다. 단일 코드를 추가 할 방법이 없으므로 현재 $codeMap
배열과 추가 할 요소를 포함하는 setCodeMap()
으로 전달할 새 배열을 만들어야합니다.
class AnotherThingFactory extends My_ThingFactory
{
public function addCodes(array $newCodes)
{
$this->setCodeMap(array_merge($this->getCodeMap(), $newCodes));
}
}
:
public function getCodeMap()
{
return $this->codeMap;
}
그런 다음 자신의 확장 클래스에서 그들이 뭔가를 할 수 있습니다 :처럼 뭔가를
My_ThingFactory
를 열고 추가하지 않고이 작업을 수행하는 (원래의 배열을 하드 코딩 이외의) 다른 방법이 없습니다
하지만 이것은 다시 클래스에 들어가 필요한 기능을 추가하기 만하면 열기/닫기 원칙을 어기는 경우에만 가능합니다. $codeMap
속성을 protected
으로 만듦으로써 이것을 바로 잡은 다음 확장 클래스가 코드를 해킹하지 않고 필요한 것을 할 수 있습니다. 또한 확장 클래스는 올바르게 조작하고 있음을 보장해야합니다.
개방형/폐쇄 형 질문에 대답하려면 : $codeMap
을 의도적으로 잠글려고하고 다른 방법으로 사용하지 않으려면 괜찮습니다. 그러나 위에 설명한대로 $codeMap
어레이를 더 잘 제어해야하는 경우이를 수행하기위한 원칙을 위반해야합니다. 제 제안은 당신이 당신의 클래스에 내장하고 싶어하는 팩토리의 관리를 브레인 스토밍하여 클래스 코어 기능의 일부로 만드는 것입니다.
테스트의 경우이 코드를 그대로 테스트 할 수없는 이유는 알 수 없습니다. 코드 맵을 설정 한 다음 create()
메서드를 사용하여 반환 된 해당 인스턴스를 테스트 할 수 있습니다.
class FactoryTest extends PHPUnit_Framework_TestCase
{
private $factory;
public function setUp()
{
$this->factory = new My_ThingFactory();
}
public function tearDown()
{
$this->factory = null;
}
public function testMadeConcreteA()
{
$this->assertInstanceOf('My_Thing_ConcreteA', $this->factory->create('A111'));
}
public function testMadeStealthBomber()
{
$this->factory->setCodeMap(array('B-52', 'StealthBomber')); //Assume the class exists.
$this->assertInstanceOf('StealthBomber', $this->factory->create('B-52'));
}
public function testDidntMakeSquat()
{
$this->assertNotInstanceOf('My_Thing_ConcreteA', $this->factory->create('Nada'));
}
}
개방형/폐쇄 형 원칙을 위반하는 것에 대해서는 다음을 읽어보십시오. [종속성 주입의 끝 - 누가 종속성을 생성합니까?] (http://www.deadschool.com/article/end-dependency-injection-who-creates- 의존성) –