2017-10-17 11 views
1

Strategy Pattern과 같은 것을 구현하고 싶습니다. 부모 메서드에서 논리를 일반화 했으므로 부모에게 특정 논리 (캐스팅 등)를 전달해야합니다.전략 패턴, 상위 메소드에 함수 전달

나는 다음과 같은 한 클래스 :

class A{ 
    public Object generateData(Function fetchData, AbstractForm form) 
    { 
     List<DataBean> dataBeans = (List<DataBean>) fetchData.apply(form); 
     //... 
    } 
} 

class B extends A{ 
    void someMethod(AbstractForm form){ 
     Function<AbstractForm, List<DataBean>> fetchFunction = new Function<AbstractForm, List<DataBean>>() { 
      //here goes form specific casting and other data fetch specific logic 
      return dataBeans; 
     } 
     super.generateData(fetchFunction, form); 
    } 
} 

내가 제대로 여기에 함수의 생각을 했습니까?

+0

이 튜토리얼이 도움이 될 것입니다. Java 8의 전략 디자인 패턴 http://www.baeldung.com/java-strategy-pattern –

+1

아이디어를 올바르게 받았는지 어떻게 인식할까요? 코드 조각을 게시하는 기능은 ... – Holger

답변

4

전략 패턴의 올바른 사용은 컨텍스트 (귀하의 사례 클래스 A)와 전략 (귀하의 경우 구현은 Function) 사이의 집계를 의미합니다.

아래 이미지 (Gang of Four 서적 Design patterns: elements of reusable object-oriented software에서 가져온 이미지)의 관계를 볼 수 있습니다. 나는이 문제에 대한 전통적인 전략 패턴 접근 방식을 적용한 아래

Strategy pattern UML

. 이 경우 Function.apply(AbstractForm)이 캐스팅의 필요성을 제거하기 위해 List<DataBean>을 반환하도록했습니다. 당연히 제네릭을 사용하여 Function을보다 융통성있게 만들 수 있습니다.

전략이 ​​경우

public interface Function { 
    List<DataBean> apply(AbstractForm form);  
} 

컨텍스트

public class A { 

    private Function fetchData; // strategy 

    public void setStrategy(Function fetchData) { // method for setting the strategy 
     this.fetchData = fetchData; 
    } 

    // precondition: fetchData != null 
    public Object generateData(AbstractForm form) { 
     List<DataBean> dataBeans = fetchData.apply(form); // using the strategy 
     return null; // whatever you want to return 
    }  
} 

, 연장 클래스 A 우리 전략 (Function) setStrategy(Function)를 사용하여 주입 수이 켜지지 아니다. 그러나 사전 정의 된 전략을 사용하여 항상 A을 훌륭한 개체로 확장 할 수 있습니다.

예를 들어

: 가능성 필요한 데이터를 가져 와서 사용 할 '기본'이 없을 수 있습니다위한 전략 있기 때문에 공장 방법

를 사용

public class B extends A { 

    public B() { 
     setStrategy((form) -> null); // implement your concrete strategy here 
    } 
} 

토록 변경할 수 없습니다, 대신 Factory 메소드 패턴을 사용하여 Product (Function) 생성을 시행 할 수 있습니다. 참고 클래스 A은 이제 추상이며 팩토리 메소드 createFunction()을 포함하며이 클래스는 서브 클래스 (예 : B)에 구현되어 Function을 생성합니다.

팩토리 메소드 패턴의 디자인은 아래의 UML에서 볼 수 있습니다. 이 경우 제품은 이전에 전략 (Function)이었고 작성자는 클래스 A이고 ConcreteCreator는 클래스 B입니다.

Factory method pattern UML

창조주

public abstract class A { 

    private Function fetchData; // product to be used 

    public class A() { 
     fetchData = createFunction(); // call factory method 
    } 

    protected abstract Function createFunction(); // factory method 

    // precondition: fetchData != null 
    public Object generateData(AbstractForm form) { 
     List<DataBean> dataBeans = fetchData.apply(form); // using the product 
     return null; // whatever you want to return 
    } 

} 

제품 고정 및 변하기 쉬워되지 않는이 경우 ConcreteCreator

public class B extends A { 

    @Override 
    protected Function createFunction() { 
     return (form) -> null; // return product 
    } 
} 

하지만,이 두 패턴을 혼합하여 극복 할 수있다 함께포함 10 첫 번째 예제에서 클래스 A에서 다시.