7

Factory Method pattern (공장 또는 초록 ​​공장 패턴과 혼동하지 말 것)이 Open/Closed principle을 위반합니까?팩토리 메서드 패턴이 열기/닫기 원칙을 위반합니까?

업데이트 : 명확한 설명을 위해 구체적인 클래스에 정적 팩터 리 메서드가있는 시나리오를 참조하고 있습니다. 예를 들어 (이것은 위키 백과 페이지에서 FMP에) :

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    private Complex(double a, double b) { 
     //... 
    } 
} 

는 개인 생성자 즉 확장, 서브 클래스되는 클래스를 방지하지 않습니다?

새 팩토리 메서드를 지원하기 위해 클래스를 수정해야합니까? 예를 들어 클래스가 처음에 fromCartesian 만 갖고 나중에 fromPolar가 필요한 경우이 클래스를 수정해야 클래스를 지원할 수 있습니까?

두 가지가 모두 열림/닫힘을 위반하지는 않습니까?

+2

는 내가 대답하기 전에 당신이 어떻게 생각하는지 알고 싶습니다. 당신의 대답은 당신이 대답을 찾고 있다고 느끼게 할 것입니다. 그렇지 않으면 당신이 당신의 일을 아웃소싱하고있는 것과 같습니다. –

+0

죄송합니다. 댓글을 달려고했지만 출퇴근을하고 있습니다. :) 나는 그것을 위반하고 있다고 생각하고 있습니다. 내가 틀렸다면 나를 바로 잡으십시오. 그러나 FMP가 개인 생성자를 지시하고 개인 생성자가 확장을 금지합니다. 또한 대체 구현을 지원하도록 클래스를 수정해야합니까? 클래스에 정적 팩토리 메서드가있는 상황을 생각하고 있습니다. 어쩌면 이것은 FMP의 유일한 맛일까요? –

+0

하위 클래스 인 경우 메소드를 덮어 쓰거나 super() (Java라고 가정)을 사용할 수 있습니다. 정적 메서드를 사용하지 않는 것이 좋으며 switch 문을 사용하여 선택하거나 제공된 구성 파일을 읽는 매개 변수를 취하는 단일 메서드를 사용하는 것이 좋습니다. –

답변

3

아니요, 개방형/폐쇄 형 원칙을 전혀 위반하지 않습니다.

열기/닫기는 이미 존재하는 코드를 수정하지 않고 시스템 작동 방식을 수정할 수 있음을 의미합니다. 코드를 확장하고 다른 방법으로 사용할 수 있지만 이전 코드는 여전히 유효하므로 다시 테스트 할 필요가 없습니다.

팩토리 메서드 패턴은 지정된 매개 변수를 기반으로 다른 유형의 개체를 만듭니다. Factory Method는 실제로 올바르게 실행되면 Open/Closed 원리로 잘 작동합니다. 그러나 새 클래스를 만든 다음 팩토리 메서드에서 해당 형식의 새 개체를 만들려면 팩터 리 메서드를 변경해야합니다.

어떤 종류의 설정 파일이나 Factory Method에 의해 읽혀질 수있는 그런 종류의 것이 있다면, Factory Method ...를 바꿀 필요가 없을 것입니다. 설정 파일은 어떤 객체를 지시합니까? Factory Method에 의해 생성됩니다.

2

아니요. 귀하의 위키 백과 링크에서 :

소프트웨어 엔티티 (클래스, 모듈, 함수 등) 확장 오픈해야하지만, 수정

공장 방법은 확장 재정의 폐쇄. 당신은 새로운 수업을 만들고 있습니다. 기존 클래스는 변경하지 않습니다. 원본의 서브 클래스를 (IoC 컨테이너 구성을 통해) 바꿔야합니다.

5

공장 패턴은 본질적으로 OCP의 위반자가 아닙니다.

에 따라 달라집니다. 어떻게하면 Complex의 동작을 취할 수 있습니다.Complex 만약

Complex 개체의 새로운 유형의 생산을 지원하는 데 필요한, 그리고 당신이 그들을 지원하기 위해 추가되는 새로운 fromX 방법을 추가하여 Complex을 수정하는 선택되어, 다음이 ComplexOCP 때문에 Complex해야하는 위반자이되는 것을 의미한다 수정을 위해 다시 열 수 : 당신은 자바 클래스를 변경할 필요없이 자신을 면제하기 위해 어떤 종류의 텍스트 파일 또는 속성 파일들로이 문제를 밀어 수

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    //class opened for modification 
    public static Complex fromOtherMeans(String x , String y) { 
     return new Complex(x, y); 
    } 
} 

,하지만 당신을 방지하지 않습니다 ord의 솔루션 영역에서 여분의 로직을 작성하지 않아도됩니다. 새로운 유형의 Complex을 지원합니다.

디자인에 따라 Complex의 용도에 따라 (다양한 유형이 어떻게 다른가요? 어떻게 사용하고 있습니까?), 적용 할 수있는 몇 가지 대체 옵션이 있습니다.

그러한 대안 중 하나는 다른 공장 방법을 제공하기 위해 Complex의 하위 클래스로 지정하는 것입니다. 하위 클래스는 Complex이 확장되었지만 수정되지 않은 방법을 보여주는 가장 간단한 그림입니다.

이 경우 Complex을 변경하는 또 다른 OCP 대체 방법은 Decorator pattern입니다. 지속적으로 Complex 수정하지 않고 새로운 기능으로 포장 확장되기 때문에 Complex 측면의 OCP를 새로운 변종을 만들 수있는 능력 Complex를 장식합니다.

세 번째 대안은 계산이 조성물에 의해 공급되도록 Complex의 구조를 변경하는 것일 수도있다. 이것은 당신에게 Complex의 다른 동작 사이 diferentiate하는 Strategy pattern를 사용 할 수있는 기회를 열어 것입니다.

팩토리 패턴에 대한 점은 상황에 맞는 코드를 존중 OCP을 할 수 있다는 것입니다. 하나는 공장 클래스와 OCP의 오른쪽에 유지하기 위해 위의 방법 중 하나를 사용 할 수 있지만 동료는, 객체 그래프 하나 개를 살펴 가능성이 단일 공장에 물건 그래프를 가지고있는 지혜를 질문 , 다시 하나의 팩토리로 단순화하여 첫 번째 예제로 돌아갑니다. 모든 그것을 를 사용하는 이유는 이러한 경우

는 오히려 SOLID 원칙을 존중하는 공장 패턴의 구현을 구부리는 것보다, 고려하십시오.

관련 문제