2013-10-31 2 views
1

클래스가 있는데, A, 즉 extends B이라고합시다. 클래스 이름을 변경하거나 확장 할 수 없습니다.제한적인 컨텍스트에서 팩토리 패턴을 구현하는 방법은 무엇입니까?

그러나 A에는 방법이 있습니다. doSomething (이름을 변경할 수 없음)이라고 가정 해 보겠습니다.

깃발에 따르면, A의 생성자로 전송되었으므로 뭔가 다른 것을 할 수 있습니다.

이러한 제한 사항이 모두 주어지면 플래그에 따라 doSomething에서 포크를 처리 할 것을 어떻게 제안합니까?

감사

답변

0

당신은 내 의견으로는이 개 옵션 중 하나를 선택할 수 있습니다

  • 이 플래그를 사용하고 doSomething 2로 내부 방법에 대한 플래그에 따라. 예를 들어 :

    public class A extends B { 
        private boolean forkFlag; 
    
        public A (boolean forkFlag) { 
         this.forkFlag = forkFlag; 
        } 
    
        public void doSomething() { 
    
         if (forkFlag) { 
         doSomething1(); 
         } else { 
         doSomething2(); 
         } 
        } 
    
        private void doSomething1() { ... } 
    
        private void doSomething2() { ... } 
    } 
    
  • 는 전략 구현을 만들기 : 그 둘 사이의 결정

    public class A extends B { 
        private boolean forkFlag; 
        private Runnable doSomethingImpl; 
    
        public A (boolean forkFlag) { 
        if(forkFlag) { 
         doSomethingImpl = new DoSomethingImpl1(); 
        } else { 
         doSomethingImpl = new DoSomethingImpl2(); 
        } 
        } 
    
        public void doSomething() { 
         doSomethingImpl.run(); 
        } 
    } 
    
    
    
    public class DoSomethingImpl1 implements Runnable { 
    public void run() { ... } 
    } 
    
    public class DoSomethingImpl2 implements Runnable { 
        public void run() { ... } 
    } 
    

필요에 따라 달라집니다. 이 포크가 사소한 것이라면, 일반적인 흐름의 유스 케이스 일뿐입니다. 첫 번째 옵션을 사용합니다. 세 번째 흐름이 필요할 수도있는 경우 전략 패턴을 사용하여 제공되는 디커플링을 즐기십시오. 전략으로

그냥 생성자를 변경하여 클래스 외부에서 원하는 구현을 주입하고 doSomething의 구현 완전히 인식 할 수있을 것이다는 :

public A (Runnable doSomething) { 
    this.doSomething = doSomething; 
} 

분사 패턴은 아마도 가장입니다 우아하고 구현에서 코드의 완벽한 분리를 만듭니다. 또한 implements Runnable을 자신의 public interface DoSomething의보다 구체적인 인터페이스로 변경하여 더욱 강력하게 만들 수 있습니다.

0

당신은 당신의 코드가 논리적으로, 성장하면 더 나은, 여기

public A(boolean flag){ 
    if(flag == true){ 
     this.service = new DoSomethingStrategy(); 
    }else{ 
     this.service = new DoSomethingElseStrategy(); 
    } 
} 

Strategy 패턴을 사용하는 생성자에 공장을 사용해야합니다 :

public A(boolean flag){ 
    this.service = DoSomethingFactory.getService(flag); 
} 

DoSomethingFactory 내부의 코드를 복사;

그리고 마지막으로 당신의 doSomething 방법

public void doSomething(){ 
    this.service.doSomething(); 
} 

및 해봐요에 대한 당신의 행동에

는 전략 구조로 캡슐화됩니다.더 자세한 정보없이

1

:

public Foo doSomething() { 
    if(flag) { 
     return super.doSomething(); 
    } else { 
     return doSomethingElse(); 
    } 
} 

당신은 전략 패턴을 사용할 수 있지만, 그것은 당신이 디자인 패턴을 적용 느낌이 아닌 약간의 이익과 코드 라인 수십를 추가합니다.

메서드 호출에서 필요한 간접 지정을 사용하면 if가 느려질 수도 있습니다.

+0

유일한 문제는 (언급되지 않음) 기본 클래스를 만질 수 없다는 것입니다. 따라서 두 클래스를 동일한 A 클래스에 넣어야합니다. – Roxana

0

왜 B를 확장하고 필요한 경우 A 대신 사용하는 다른 클래스 C를 만들 수 없습니까? 가능한 경우 조건부를 피하고 클래스 내에서 전략을 구성하는 것을 하드 코딩하는 것이 좋습니다.

기본 클래스를 만질 필요없이 다른 구현으로 확장하면됩니다.

관련 문제